1 Project setup

1.0.1 Packages

Install packages if necessary. Listed are installers for packages not on CRAN and the devlopment (most up-to-date) version of STEPS.

# library(devtools)
# install_github("steps-dev/steps")
# install_github("smwindecker/gdaltools")

Load packages

library(raster)
Loading required package: sp
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:raster’:

    intersect, select, union

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union
library(tibble)
library(sf)
Linking to GEOS 3.6.2, GDAL 2.2.3, PROJ 4.9.3
library(rgdal)
rgdal: version: 1.4-3, (SVN revision 828)
 Geospatial Data Abstraction Library extensions to R successfully loaded
 Loaded GDAL runtime: GDAL 2.2.3, released 2017/11/20
 Path to GDAL shared files: /usr/share/gdal/2.2
 GDAL binary built with GEOS: TRUE 
 Loaded PROJ.4 runtime: Rel. 4.9.3, 15 August 2016, [PJ_VERSION: 493]
 Path to PROJ.4 shared files: (autodetected)
 Linking to sp version: 1.3-1 
library(readr)
library(readxl)
library(ggplot2)
library(lubridate)

Attaching package: ‘lubridate’

The following object is masked from ‘package:base’:

    date
library(magrittr)

Attaching package: ‘magrittr’

The following object is masked from ‘package:raster’:

    extract
library(tidyr)

Attaching package: ‘tidyr’

The following object is masked from ‘package:magrittr’:

    extract

The following object is masked from ‘package:raster’:

    extract
library(foreach)
library(doMC)
Loading required package: iterators
Loading required package: parallel
library(future)

Attaching package: ‘future’

The following object is masked from ‘package:raster’:

    values
library(future.apply)
library(tidyr)
library(dismo)
library(gbm)
Loaded gbm 2.1.5
library(steps)
library(gdaltools)

1.0.2 Functions

source(file = "R/functions/pg.sf.R")
source(file = "R/functions/pg.pa.R")
source(file = "R/functions/read.vba.R")
source(file = "R/functions/proc.vba.R")
source(file = "R/functions/get.landis.vars.R")
source(file = "R/functions/rascc.R")
source(file = "R/functions/read.multi.line.header.R")
source(file = "R/functions/interpolate.climdat.R")
source(file = "R/functions/get.rst.prop.R")
source(file = "R/functions/get.rst.dat.R")

1.0.3 Paths

proj_path <- "/home/landis/rfst/"
# proj_path <- "D:/Users/ryan/Dropbox/Work/RFA_STEPS/rfst/"

2 Prepare variables

2.1 Analysis parameters

2.1.1 Timesteps

ntimesteps <- 50
ncores <- 20

2.2 Geographic data

2.2.1 Landscape

Set up base landscape layer

ch_rst <- raster(x = "data/grids/eco_v12.img") %T>%
  plot

ch_proj <- ch_rst@crs
ch_extent <- extent(ch_rst)
ch_res <- res(ch_rst)

2.2.2 Boundaries

rfa <- read_sf("data/shapefiles/RFA/")%>%
  st_transform(crs = ch_proj)
rfa
Simple feature collection with 81 features and 7 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: -57985.97 ymin: 5665387 xmax: 763088.7 ymax: 6223446
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs
pg.sf(rfa)

ch_rfa <- rfa[rfa$NAME== "CENTRAL HIGHLANDS",] 
ch_rfa
Simple feature collection with 1 feature and 7 fields
geometry type:  POLYGON
dimension:      XY
bbox:           xmin: 318074.3 ymin: 5770575 xmax: 452175.7 ymax: 5906852
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs
pg.sf(ch_rfa)

ch_mask <- rasterize(ch_rfa, ch_rst, field = 1, filename = "./output/landscape_vars/ch_mask.grd", overwrite = TRUE) 
ch_mask[ch_rst == 132] <- NA # removes lake areas from habitat
plot(ch_mask)

Think carefully about using this layer as projections are for zone 55, so distorts west of the state

victoria <- read_sf("data/shapefiles/vicstatepolygon/") %>%
   st_transform(crs = ch_proj)

2.3 Occurrence data

pseudo_abs <- read_sf("data/shapefiles/pseudo_absences/pseudo_absences.shp")%>%
  st_transform(crs = st_crs(ch_rst)) %>%
  mutate(PA = 0) %>%
  select(PA, geometry) %>%
  st_zm(drop = TRUE)
pseudo_abs
Simple feature collection with 35 features and 1 field
geometry type:  POINT
dimension:      XY
bbox:           xmin: 325312 ymin: 5774360 xmax: 445518.4 ymax: 5901431
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs

2.3.1 GG Occurrence data

Read in data

gg_ari <- read_excel(path = "data/tabular/BoA_SB_Combined_VBA_upload_v4.xls") %>%
  dplyr::select(-starts_with("leave")) %>%
  rename("lon" = `X-coordinate (easting or longitude)`, "lat" = `Y-coordinate (northing or latitude)`) %>%
   fill(lon, lat, .direction = "down") %>%
  filter(`Taxon Name` == "Misc Target taxa not found") %>%
  select(lon, lat) %>%
  mutate(PA = 0) %>%
  st_as_sf(coords = c("lon", "lat"), crs = st_crs(28355)) %>%
  st_transform(crs = st_crs(ch_rst))

-
/
                                                                                                                  
New names:
* `leave blank` -> `leave blank...2`
* `leave blank` -> `leave blank...3`
* `leave blank` -> `leave blank...6`
* `leave blank` -> `leave blank...7`
* `leave blank` -> `leave blank...25`
gg_ari
Simple feature collection with 51 features and 1 field
geometry type:  POINT
dimension:      XY
bbox:           xmin: 333214 ymin: 5779763 xmax: 451285 ymax: 5937215
epsg (SRID):    28355
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs
gg_vba <- proc.vba("data/tabular/vba_gg_all_20190509.csv", project.crs = ch_proj)
gg_vba
Simple feature collection with 3086 features and 1 field
geometry type:  POINT
dimension:      XY
bbox:           xmin: 248825.6 ymin: 5725915 xmax: 742929.5 ymax: 6008846
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs
gg_pa_all <- gg_vba %>%
  rbind(gg_ari)
gg_pa_all
Simple feature collection with 3137 features and 1 field
geometry type:  POINT
dimension:      XY
bbox:           xmin: 248825.6 ymin: 5725915 xmax: 742929.5 ymax: 6008846
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs
plot_gg_pa_all <- pg.pa(gg_pa_all, ch_rfa) +
  geom_sf(data = victoria, fill = NA)
Coordinate system already present. Adding new coordinate system, which will replace the existing one.
plot_gg_pa_all

gg_pa_ch <- gg_pa_all[ch_rfa,]
gg_pa_ch
Simple feature collection with 1308 features and 1 field
geometry type:  POINT
dimension:      XY
bbox:           xmin: 333053.7 ymin: 5783845 xmax: 448916.2 ymax: 5887474
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs
gg_pa_ch_psab <- gg_pa_ch %>%
  rbind(pseudo_abs)
st_write(gg_pa_ch, "output/shapefiles/pa/ch/gg_pa_ch.shp", delete_layer = TRUE)
Deleting layer `gg_pa_ch' using driver `ESRI Shapefile'
Writing layer `gg_pa_ch' to data source `output/shapefiles/pa/ch/gg_pa_ch.shp' using driver `ESRI Shapefile'
features:       1308
fields:         1
geometry type:  Point
st_write(gg_pa_ch_psab, "output/shapefiles/pa/ch/gg_pa_ch_psab.shp", delete_layer = TRUE)
Deleting layer `gg_pa_ch_psab' using driver `ESRI Shapefile'
Writing layer `gg_pa_ch_psab' to data source `output/shapefiles/pa/ch/gg_pa_ch_psab.shp' using driver `ESRI Shapefile'
features:       1343
fields:         1
geometry type:  Point
pg_gg_pa_ch <- pg.pa(gg_pa_ch %>% mutate(pseudo_abs = "vba") %>% rbind(pseudo_abs %>% mutate(pseudo_abs = "pseudo_absences")), ch_rfa) +
  facet_grid(.~pseudo_abs)
pg_gg_pa_ch

2.3.2 LBP Occurrence data

lb_pa_all <- proc.vba("data/tabular/vba_lb_all_20190509.csv", project.crs = ch_proj)
plot_lb_pa_all <- pg.pa(lb_pa_all, ch_rfa) +
  geom_sf(data = victoria, fill = NA)
Coordinate system already present. Adding new coordinate system, which will replace the existing one.
plot_lb_pa_all

lb_pa_ch <- lb_pa_all[ch_rfa,]
lb_pa_ch
Simple feature collection with 1404 features and 1 field
geometry type:  POINT
dimension:      XY
bbox:           xmin: 364618.3 ymin: 5798912 xmax: 447312.4 ymax: 5868055
epsg (SRID):    NA
proj4string:    +proj=utm +zone=55 +south +ellps=GRS80 +towgs84=0,0,0,-0,-0,-0,0 +units=m +no_defs
lb_pa_ch_psab <- lb_pa_ch %>%
  rbind(pseudo_abs)
st_write(lb_pa_ch, "output/shapefiles/pa/ch/lb_pa_ch.shp", delete_layer = TRUE)
Deleting layer `lb_pa_ch' using driver `ESRI Shapefile'
Writing layer `lb_pa_ch' to data source `output/shapefiles/pa/ch/lb_pa_ch.shp' using driver `ESRI Shapefile'
features:       1404
fields:         1
geometry type:  Point
st_write(lb_pa_ch_psab, "output/shapefiles/pa/ch/lb_pa_ch_psab.shp", delete_layer = TRUE)
Deleting layer `lb_pa_ch_psab' using driver `ESRI Shapefile'
Writing layer `lb_pa_ch_psab' to data source `output/shapefiles/pa/ch/lb_pa_ch_psab.shp' using driver `ESRI Shapefile'
features:       1439
fields:         1
geometry type:  Point
pg_lb_pa_ch <- pg.pa(lb_pa_ch %>% mutate(pseudo_abs = "vba") %>% rbind(pseudo_abs %>% mutate(pseudo_abs = "pseudo_absences")), ch_rfa) +
  facet_grid(.~pseudo_abs)
pg_lb_pa_ch

save.image("output/session_images/landscape-occupancy.RData")
#load(file = "output/session_images/landscape-occupancy.RData")

2.4 Landis output

2.4.1 Scenario 1: Current planned burning, current timber harvesting, climate change under RCP 4.5, current bushfire regime (Buisness as usual)

s1_vars_landis <- get.landis.vars(
  scn_path = "~/landis_ch_s1_pb-th-cc_50/",
  proj_path = proj_path,
  out_path = "/output/habitat_vars/",
  scn_id = "s1",
  proj_mask = ch_mask,
  timesteps = ntimesteps,
  cores = ncores
  )
plot(s1_vars_landis[[1]])

plot(s1_vars_landis[[ntimesteps + 1]])

save(s1_vars_landis, file = "output/habitat_vars/s1_vars_landis")
# load(file = "output/habitat_vars/s1_vars_landis_fut")

2.4.2 Scenario 2: Current planned burning, current timber harvesting, climate change under RCP 8.5, increatred bushfire regime

2.4.3 Scenario 3: Current planned burning, current timber harvesting, no climate change, current bushfire regime

s3_vars_landis <- get.landis.vars(
  scn_path = "~/landis_ch_s3_pb-th-cc0_50/",
  proj_path = proj_path,
  out_path = "/output/habitat_vars/",
  scn_id = "s3",
  proj_mask = ch_mask,
  timesteps = ntimesteps,
  cores = ncores
  )
plot(s3_vars_landis[[1]])

plot(s3_vars_landis[[ntimesteps + 1]])

save(s3_vars_landis, file = "output/habitat_vars/s3_vars_landis")
# load(file = "output/habitat_vars/s3_vars_landis_fut")

2.4.4 Scenario 4: Current planned burning, no harvesting, climate change under RCP 4.5, current bushfire regime

s4_vars_landis <- get.landis.vars(
  scn_path = "~/landis_ch_s4_pb-th0-cc_50/",
  proj_path = proj_path,
  out_path = "/output/habitat_vars/",
  scn_id = "s4",
  proj_mask = ch_mask,
  timesteps = ntimesteps,
  cores = ncores,
  harvest_timber = FALSE
  )
plot(s4_vars_landis[[1]])

plot(s4_vars_landis[[ntimesteps + 1]])

save(s4_vars_landis, file = "output/habitat_vars/s4_vars_landis")
# load(file = "output/habitat_vars/s4_vars_landis_fut")

2.5 ARI Data

2.5.1 Anisotronic heating x ruggedness

ahr <-raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/Anisotrophic_Heating_Ruggedness") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_ahr.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.2 Log verticical distance all wetlands

lvdaw <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/log_vertical_distance_all_wetlands_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_lvdaw.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.3 Log vertical distance major streams

lvdma <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/log_vertical_distance_major_streams_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_lvdma.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.4 Log vertical distance minor streams

lvdmi <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/log_vertical_distance_minor_streams_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask) %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.5 Log vertical distance saline wetlands

lvdsw <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/log_vertical_distance_saline_wetlands_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_lvdsw.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.6 Relative annual insolation

rai <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/relative_annual_insolation_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_rai.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.7 Thorium

tho <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/sept2014thorium") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_tho.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.8 Visible sky index

vsky <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/visible_sky_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_vsky.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.9 Topographic wetness index

twi <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/wetness_index_topocrop_sept2012") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/habitat_vars/ari_twi.grd") %T>%
  plot
no non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf

2.5.10 Wind exposition

Problem with layer

# winex <- raster(x = "data/grids/Env_covariates_noClimate_VicGrid94/wind_exposition2015") %>%
  # projectRaster(to = ch_mask) %>%
  # mask(mask = ch_mask, filename = "output/habitat_vars/ari_winex.grd") %T>%
  # plot

2.5.11 ARI variables stack

2.5.11.1 Initial variables

ari_iv <- stack(lvdaw, lvdma, lvdmi, lvdsw)
names(ari_iv) <- c("lvdaw", "lvdma", "lvdmi", "lvdsw")

2.5.11.2 Future variables

Repeates into list for each year

ari_v <- vector("list", ntimesteps + 1)
for(i in 1:(ntimesteps+1)){
  ari_v[[i]] <- ari_iv
}

2.6 Climactic data

pc ~ percentage change ac ~ absolute change

tmax ~ max temperature tmin ~ minimum temperature prec ~ precipitation evtr ~ evapotranspiration

01 ~ January 07 ~ July

4.5 ~ rcp 4.5 8.5 ~ rcp 8.5

2.6.1 Current climate

From WorldClim

2.6.1.1 Precipitation in January

prec01 <- raster("data/grids/wc2.0_30s_prec_01.tif") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/clim_vars/prec01.grd")
3 projected point(s) not finiteno non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf
names(prec01) <- "prec01"
plot(prec01)

2.6.1.2 Precipitation in July

prec07 <- raster("data/grids/wc2.0_30s_prec_07.tif") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/clim_vars/prec07.grd")
3 projected point(s) not finiteno non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf
names(prec07) <- "prec07"
plot(prec07)

2.6.1.3 Max temperature in January

tmax01 <- raster("data/grids/wc2.0_30s_tmax_01.tif") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/clim_vars/tmax01.grd")
3 projected point(s) not finiteno non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf
names(tmax01) <- "tmax01"
plot(tmax01)

2.6.1.4 Minimum temperature in July

tmin07 <- raster("data/grids/wc2.0_30s_tmin_07.tif") %>%
  projectRaster(to = ch_mask) %>%
  mask(mask = ch_mask, filename = "output/clim_vars/tmin07.grd")
3 projected point(s) not finiteno non-missing arguments to min; returning Infno non-missing arguments to max; returning -Inf
names(tmin07) <- "tmin07"
plot(tmin07)

2.6.2 Future climate

Data from Climate Change in Australia

2.6.2.1 Change data

CV has updated ##### Absolute change in temperature

#absolute change in temp
raw_tmax01_4.5_ac <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/tasmax_Amon_CSIRO-Mk3-6-0_rcp45_r1i1p1_abs-change-wrt-seasavg-clim_native.csv?tasmax_january[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")

raw_tmax01_8.5_ac <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/tasmax_Amon_CSIRO-Mk3-6-0_rcp85_r1i1p1_abs-change-wrt-seasavg-clim_native.csv?tasmax_january[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")

raw_tmin07_4.5_ac <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/tasmin_Amon_CSIRO-Mk3-6-0_rcp45_r1i1p1_abs-change-wrt-seasavg-clim_native.csv?tasmin_july[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]") 

raw_tmin07_8.5_ac <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/tasmin_Amon_CSIRO-Mk3-6-0_rcp85_r1i1p1_abs-change-wrt-seasavg-clim_native.csv?tasmin_july[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")

Years data

n_tmax01_4.5 <- as.numeric(sub("-.*", "", unique(raw_tmax01_4.5_ac$time)))
n_tmax01_8.5 <- as.numeric(sub("-.*", "", unique(raw_tmax01_8.5_ac$time)))
n_tmin07_4.5 <- as.numeric(sub("-.*", "", unique(raw_tmin07_4.5_ac$time)))
n_tmin07_8.5 <- as.numeric(sub("-.*", "", unique(raw_tmin07_8.5_ac$time)))
tmax01_4.5_ac <- rascc(raw_tmax01_4.5_ac, new.proj.layer = ch_mask)
tmax01_8.5_ac <- rascc(raw_tmax01_8.5_ac, new.proj.layer = ch_mask)
tmin07_4.5_ac <- rascc(raw_tmin07_4.5_ac, new.proj.layer = ch_mask)
tmin07_8.5_ac <- rascc(raw_tmin07_8.5_ac, new.proj.layer = ch_mask)

2.6.3 Percentage change in precipitation

raw_prec01_4.5_pc <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/pr_Amon_CSIRO-Mk3-6-0_rcp45_r1i1p1_perc-change-wrt-seassum-clim_native.csv?pr_january[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")

raw_prec01_8.5_pc <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/pr_Amon_CSIRO-Mk3-6-0_rcp85_r1i1p1_perc-change-wrt-seassum-clim_native.csv?pr_january[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")

raw_prec07_4.5_pc <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/pr_Amon_CSIRO-Mk3-6-0_rcp45_r1i1p1_perc-change-wrt-seassum-clim_native.csv?pr_july[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")

raw_prec07_8.5_pc <- read.multi.line.header(file = "http://nrm-erddap.nci.org.au/erddap/griddap/pr_Amon_CSIRO-Mk3-6-0_rcp85_r1i1p1_perc-change-wrt-seassum-clim_native.csv?pr_july[(2025-01-01T12:00:00Z):1:(2090-01-01T12:00:00Z)][(-40.10297775):1:(-32.64199448)][(140.625):1:(150)]")
prec01_4.5_pc <- rascc(raw_prec01_4.5_pc, new.proj.layer = ch_mask)
prec01_8.5_pc <- rascc(raw_prec01_8.5_pc, new.proj.layer = ch_mask)
prec07_4.5_pc <- rascc(raw_prec07_4.5_pc, new.proj.layer = ch_mask)
prec07_8.5_pc <- rascc(raw_prec07_8.5_pc, new.proj.layer = ch_mask)
n_prec01_4.5 <- as.numeric(sub("-.*", "", unique(raw_prec01_4.5_pc$time)))
n_prec01_8.5 <- as.numeric(sub("-.*", "", unique(raw_prec01_4.5_pc$time)))
n_prec07_4.5 <- as.numeric(sub("-.*", "", unique(raw_prec07_4.5_pc$time)))
n_prec07_8.5 <- as.numeric(sub("-.*", "", unique(raw_prec07_4.5_pc$time)))

2.6.4 Absolute predicted values

2.6.4.1 Temperature

add new function that writes these climate layers to files.

2.6.4.1.1 Jan max temperature RCP 4.5
tmax01_4.5 <- tmax01_4.5_ac + tmax01
names(tmax01_4.5) <- names(tmax01_4.5_ac)
plot(tmax01_4.5)
2.6.4.1.2 Jan max temperature RCP 8.5
tmax01_8.5 <- tmax01_8.5_ac + tmax01
names(tmax01_8.5) <- names(tmax01_8.5_ac)
plot(tmax01_8.5)
2.6.4.1.3 July min temperature RCP 4.5
tmin07_4.5 <- tmin07_4.5_ac + tmax01
names(tmin07_4.5) <- names(tmin07_4.5_ac)
plot(tmin07_4.5)
2.6.4.1.4 July min temperature RCP 8.5
tmin07_8.5 <- tmin07_8.5_ac + tmax01
names(tmin07_8.5) <- names(tmin07_8.5_ac)
plot(tmin07_8.5)

2.6.4.2 Precipitation

2.6.4.3 January precipitation RCP 4.5

prec01_4.5 <- prec01 * (1 + prec01_4.5_pc/100)
names(prec01_4.5) <- names(prec01_4.5_pc)
plot(prec01_4.5)

2.6.4.4 January precipitation RCP 8.5

prec01_8.5 <- prec01 * (1 + prec01_8.5_pc/100)
names(prec01_8.5) <- names(prec01_8.5_pc)
plot(prec01_8.5)

2.6.4.5 July precipitation RCP 4.5

prec07_4.5 <- prec07 * (1 + prec07_4.5_pc/100)
names(prec07_4.5) <- names(prec07_4.5_pc)
plot(prec07_4.5)

2.6.4.6 July precipitation RCP 8.5

prec07_8.5 <- prec07 * (1 + prec07_8.5_pc/100)
names(prec07_8.5) <- names(prec07_8.5_pc)
plot(prec07_8.5)

2.6.5 Interploate prediction data

Currently just repeats predictions, need updating to weight predictions within 10 years, cf data from CSIRO

tmax01_4.5_int <- interpolate.climdat(tmax01, tmax01_4.5, ny = 50, nf = n_tmax01_4.5, n0 = 2019, varname = "tmax01")
tmax01_8.5_int <- interpolate.climdat(tmax01, tmax01_8.5, ny = 50, nf = n_tmax01_8.5, n0 = 2019, varname = "tmax01")
tmin07_4.5_int <- interpolate.climdat(tmin07, tmin07_4.5, ny = 50, nf = n_tmin07_4.5, n0 = 2019, varname = "tmin07")
tmin07_8.5_int <- interpolate.climdat(tmin07, tmin07_8.5, ny = 50, nf = n_tmin07_8.5, n0 = 2019, varname = "tmin07")

prec01_4.5_int <- interpolate.climdat(prec01, prec01_4.5, ny = 50, nf = n_prec01_4.5, n0 = 2019, varname = "prec01")
prec01_8.5_int <- interpolate.climdat(prec01, prec01_8.5, ny = 50, nf = n_prec01_8.5, n0 = 2019, varname = "prec01")
prec07_4.5_int <- interpolate.climdat(prec07, prec07_4.5, ny = 50, nf = n_prec07_4.5, n0 = 2019, varname = "prec07")
prec07_8.5_int <- interpolate.climdat(prec07, prec07_8.5, ny = 50, nf = n_prec07_8.5, n0 = 2019, varname = "prec07")

2.6.6 Climate variable sets

2.6.6.1 Initial climate variables

clim_iv <- stack(prec01, prec07, tmax01, tmin07)

2.6.6.2 Future climate variables

clim_fv_cc0 <- vector("list", 50)
for(i in 1:50){
  clim_fv_cc0[[i]] <- clim_iv
}


clim_fv_4.5 <- mapply(prec01_4.5_int, prec07_4.5_int, tmax01_4.5_int, tmin07_4.5_int, FUN = stack)
clim_fv_8.5 <- mapply(prec01_8.5_int, prec07_8.5_int, tmax01_8.5_int, tmin07_8.5_int, FUN = stack)
save.image(file = "output/input_variables.RData")

2.7 Distribution model variables

2.7.1 Species LANDIS variables

2.7.1.1 GG LANDIS vars

gglv <- c("ggf", "ggd", "hbt_1k")

2.7.1.2 LB LANDIS vars

lblv <- c("lbm", "hbt_3h")

2.7.2 Scenario 1

2.7.2.1 Greater Glider

2.7.2.1.1 Scenario 1 initial variables
s1_iv_gg <- stack(s1_vars_landis_init[[c(gglv)]], clim_iv)

save(s1_iv_gg, file = "output/habitat_vars/s1_iv_gg")
2.7.2.1.2 Scenaio 1 model data
s1_md_gg <- s1_iv_gg %>%
  raster::extract(y = st_coordinates(gg_pa_ch)) %>%
  cbind("PA" = gg_pa_ch$PA, .) %>%
  as.data.frame %>%
  na.omit 

s1_md_gg

save(s1_md_gg, file = "output/habitat_vars/s1_md_gg")
2.7.2.1.3 Scenario 1 future variables
s1_fv_gg <- s1_vars_landis_fut %>%
  sapply("[[", gglv) %>%
  mapply(clim_fv_4.5, FUN = stack)

save(s1_fv_gg, file = "output/habitat_vars/s1_fv_gg")

2.7.2.2 Leadbeater’s Possum

2.7.2.2.1 Scenario 1 initial variables
s1_iv_lb <- stack(s1_vars_landis_init[[c(lblv)]], clim_iv)

save(s1_iv_lb, file = "output/habitat_vars/s1_iv_lb")
2.7.2.2.2 Scenaio 1 model data
s1_md_lb <- s1_iv_lb %>%
  raster::extract(y = st_coordinates(lb_pa_ch)) %>%
  cbind("PA" = lb_pa_ch$PA, .) %>%
  as.data.frame %>%
  na.omit 

s1_md_lb

save(s1_md_lb, file = "output/habitat_vars/s1_md_lb")
2.7.2.2.3 Scenario 1 future variables
s1_fv_lb <- s1_vars_landis_fut %>%
  sapply("[[", lblv) %>%
  mapply(clim_fv_4.5, FUN = stack)

save(s1_fv_lb, file = "output/habitat_vars/s1_fv_lb")

2.7.3 Scenario 2

awaiting updated climate variables

2.7.4 Scenario 3

2.7.4.1 Greater Glider

2.7.4.1.1 Scenario 3 initial variables
s3_iv_gg <- stack(s3_vars_landis_init[[c(gglv)]], clim_iv)

save(s3_iv_gg, file = "output/habitat_vars/s3_iv_gg")
2.7.4.1.2 Scenaio 3 model data
s3_md_gg <- s3_iv_gg %>%
  raster::extract(y = st_coordinates(gg_pa_ch)) %>%
  cbind("PA" = gg_pa_ch$PA, .) %>%
  as.data.frame %>%
  na.omit 

s3_md_gg

save(s3_md_gg, file = "output/habitat_vars/s3_md_gg")
2.7.4.1.3 Scenario 3 future variables
s3_fv_gg <- s3_vars_landis_fut %>%
  sapply("[[", gglv) %>%
  mapply(clim_fv_cc0, FUN = stack)

save(s3_fv_gg, file = "output/habitat_vars/s3_fv_gg")

2.7.4.2 Leadbeater’s Possum

2.7.4.2.1 Scenario 3 initial variables
s3_iv_lb <- stack(s3_vars_landis_init[[c(lblv)]], clim_iv)

save(s3_iv_lb, file = "output/habitat_vars/s3_iv_lb")
2.7.4.2.2 Scenaio 3 model data
s3_md_lb <- s3_iv_lb %>%
  raster::extract(y = st_coordinates(lb_pa_ch)) %>%
  cbind("PA" = lb_pa_ch$PA, .) %>%
  as.data.frame %>%
  na.omit 

s3_md_lb

save(s3_md_lb, file = "output/habitat_vars/s3_md_lb")
2.7.4.2.3 Scenario 3 future variables
s3_fv_lb <- s3_vars_landis_fut %>%
  sapply("[[", lblv) %>%
  mapply(clim_fv_cc0, FUN = stack)

save(s3_fv_lb, file = "output/habitat_vars/s3_fv_lb")

2.7.5 Scenario 4

2.7.5.1 Greater Glider

2.7.5.1.1 Scenario 4 initial variables
s4_iv_gg <- stack(s4_vars_landis_init[[c(gglv)]], clim_iv)

save(s4_iv_gg, file = "output/habitat_vars/s4_iv_gg")
2.7.5.1.2 Scenaio 4 model data
s4_md_gg <- s4_iv_gg %>%
  raster::extract(y = st_coordinates(gg_pa_ch)) %>%
  cbind("PA" = gg_pa_ch$PA, .) %>%
  as.data.frame %>%
  na.omit 

s4_md_gg

save(s4_md_gg, file = "output/habitat_vars/s4_md_gg")
2.7.5.1.3 Scenario 4 future variables
s4_fv_gg <- s4_vars_landis_fut %>%
  sapply("[[", gglv) %>%
  mapply(clim_fv_4.5, FUN = stack)

save(s4_fv_gg, file = "output/habitat_vars/s4_fv_gg")

2.7.5.2 Leadbeater’s Possum

2.7.5.2.1 Scenario 4 initial variables
s4_iv_lb <- stack(s4_vars_landis_init[[c(lblv)]], clim_iv)

save(s4_iv_lb, file = "output/habitat_vars/s4_iv_lb")
2.7.5.2.2 Scenaio 4 model data
s4_md_lb <- s4_iv_lb %>%
  raster::extract(y = st_coordinates(lb_pa_ch)) %>%
  cbind("PA" = lb_pa_ch$PA, .) %>%
  as.data.frame %>%
  na.omit 

s4_md_lb

save(s4_md_lb, file = "output/habitat_vars/s4_md_lb")
2.7.5.2.3 Scenario 4 future variables
s4_fv_lb <- s4_vars_landis_fut %>%
  sapply("[[", lblv) %>%
  mapply(clim_fv_4.5, FUN = stack)

save(s4_fv_lb, file = "output/habitat_vars/s4_fv_lb")

3 Distribution model fit and prediction

3.1 Greater Glider

3.1.1 Scenario 1

s1_mod_gg <- gbm.step(data = s1_md_gg, gbm.x = 2:8, gbm.y = 1, family = "bernoulli", tree.complexity = 5, learning.rate = 0.001, step.size = 1, bag.fraction = 0.5, prev.stratify = FALSE, verbose = FALSE, max.trees = 1000)
summary(s1_mod_gg)
#s1_ip_gg <- predict(s1_iv_gg, s1_mod_gg, type = "response", n.trees = s1_mod_gg$gbm.call$best.trees, filename = "output/habitat_pred/s1_fp_gg-000.tif")

#writeRaster(s1_ip_gg, "output/habitat_pred/s1_ip_gg.tif", overwrite = TRUE)
s1_ip_gg <- raster(x = "output/habitat_pred/s1_ip_gg.tif")

plot(s1_ip_gg)
registerDoMC(cores = 20)

s1_fp_gg <- foreach(i = seq_len(length(s1_fv_gg))) %dopar% {
  predict(s1_fv_gg[[i]],
          s1_mod_gg,
          type = "response",
          n.trees = s1_mod_gg$gbm.call$best.trees,
          filename = paste0("output/habitat_pred/s1_fp_gg-", sprintf("%03d", i), ".tif"),
          overwrite = TRUE)
}

s1_fp_gg <- stack(s1_fp_gg)
save(s1_fp_gg, file = "output/habitat_pred/s1_fp_gg")
writeRaster(s1_fp_gg, filename = "output/habitat_pred/s1_fp_gg.tif")

3.1.2 Scenario 3

s3_mod_gg <- gbm.step(data = s3_md_gg, gbm.x = 3:7, gbm.y = 1, family = "bernoulli", tree.complexity = 5, learning.rate = 0.001, step.size = 1, bag.fraction = 0.5, prev.stratify = FALSE, verbose = FALSE, max.trees = 1000)
summary(s3_mod_gg)
 # s3_ip_gg <- predict(s3_iv_gg, s3_mod_gg, type = "response", n.trees = s3_mod_gg$gbm.call$best.trees, filename ="output/habitat_pred/s3_fp_gg-000.tif")

 # writeRaster(s3_ip_gg, "output/habitat_pred/s3_ip_gg.tif", overwrite = TRUE)

s3_ip_gg <- raster(x = "output/habitat_pred/s3_ip_gg.tif")

plot(s3_ip_gg)
registerDoMC(cores = 20)

s3_fp_gg <- foreach(i = seq_len(length(s3_fv_gg))) %dopar% {
  predict(s3_fv_gg[[i]],
          s3_mod_gg,
          type = "response",
          n.trees = s3_mod_gg$gbm.call$best.trees,
          filename = paste0("output/habitat_pred/s3_fp_gg-", sprintf("%03d", i), ".tif"),
          overwrite = TRUE)
}

s3_fp_gg <- stack(s3_fp_gg)
save(s3_fp_gg, file = "output/habitat_pred/s3_fp_gg")
writeRaster(s3_fp_gg, filename = "output/habitat_pred/s3_fp_gg.tif")

3.1.3 Scenario 4

s4_mod_gg <- gbm.step(data = s4_md_gg, gbm.x = 2:8, gbm.y = 1, family = "bernoulli", tree.complexity = 5, learning.rate = 0.001, step.size = 1, bag.fraction = 0.5, prev.stratify = FALSE, verbose = FALSE, max.trees = 1000)
summary(s4_mod_gg)
# s4_ip_gg <- predict(s4_iv_gg, s4_mod_gg, type = "response", n.trees = s4_mod_gg$gbm.call$best.trees,  filename = "output/habitat_pred/4_fp_gg-000.tif")

# writeRaster(s4_ip_gg, "output/habitat_pred/s4_ip_gg.tif", overwrite = TRUE)

s4_ip_gg <- raster(x = "output/habitat_pred/s4_ip_gg.tif")

plot(s4_ip_gg)
registerDoMC(cores = 20)

s4_fp_gg <- foreach(i = seq_len(length(s4_fv_gg))) %dopar% {
  predict(s4_fv_gg[[i]],
          s4_mod_gg,
          type = "response",
          n.trees = s4_mod_gg$gbm.call$best.trees,
          filename = paste0("output/habitat_pred/s4_fp_gg-", sprintf("%03d", i), ".tif"),
          overwrite = TRUE)
}

s4_fp_gg <- stack(s4_fp_gg)
save(s4_fp_gg, file = "output/habitat_pred/s4_fp_gg")
writeRaster(s4_fp_gg, filename = "output/habitat_pred/s4_fp_gg.tif")

3.2 Leadbeater’s Possum

3.2.1 Scenario 1

s1_mod_lb <- gbm.step(data = s1_md_lb, gbm.x = 2:7, gbm.y = 1, family = "bernoulli", tree.complexity = 5, learning.rate = 0.001, step.size = 1, bag.fraction = 0.5, prev.stratify = FALSE, verbose = FALSE, max.trees = 1000)
summary(s1_mod_lb)
# s1_ip_lb <- predict(s1_iv_lb, s1_mod_lb, type = "response", n.trees = s1_mod_lb$gbm.call$best.trees, filename = "output/habitat_pred/s1_fp_lb-000.tif")

# writeRaster(s1_ip_lb, "output/habitat_pred/s1_ip_lb.tif", overwrite = TRUE)

s1_ip_lb <- raster(x = "output/habitat_pred/s1_ip_lb.tif")

plot(s1_ip_lb)
registerDoMC(cores = 20)

s1_fp_lb <- foreach(i = seq_len(length(s1_fv_lb))) %dopar% {
  predict(s1_fv_lb[[i]],
          s1_mod_lb,
          type = "response",
          n.trees = s1_mod_lb$gbm.call$best.trees,
          filename = paste0("output/habitat_pred/s1_fp_lb-", sprintf("%03d", i), ".tif"),
          overwrite = TRUE)
}

s1_fp_lb <- stack(s1_fp_lb)
save(s1_fp_lb, file = "output/habitat_pred/s1_fp_lb")
writeRaster(s1_fp_lb, filename = "output/habitat_pred/s1_fp_lb.tif")

3.2.2 Scenario 3

s3_mod_lb <- gbm.step(data = s3_md_lb, gbm.x = 2:7, gbm.y = 1, family = "bernoulli", tree.complexity = 5, learning.rate = 0.001, step.size = 1, bag.fraction = 0.5, prev.stratify = FALSE, verbose = FALSE, max.trees = 1000)
summary(s3_mod_lb)
# s3_ip_lb <- predict(s3_iv_lb, s3_mod_lb, type = "response", n.trees = s3_mod_lb$gbm.call$best.trees, filename = "output/habitat_pred/s3_fp_lb-000.tif")

# writeRaster(s3_ip_lb, "output/habitat_pred/s3_ip_lb.tif", overwrite = TRUE)

s3_ip_lb <- raster(x = "output/habitat_pred/s3_ip_lb.tif")

plot(s3_ip_lb)
registerDoMC(cores = 20)

s3_fp_lb <- foreach(i = seq_len(length(s3_fv_lb))) %dopar% {
  predict(s3_fv_lb[[i]],
          s3_mod_lb,
          type = "response",
          n.trees = s3_mod_lb$gbm.call$best.trees,
          filename = paste0("output/habitat_pred/s3_fp_lb-", sprintf("%03d", i), ".tif"),
          overwrite = TRUE)
}

s3_fp_lb <- stack(s3_fp_lb)
save(s3_fp_lb, file = "output/habitat_pred/s3_fp_lb")
writeRaster(s3_fp_lb, filename = "output/habitat_pred/s3_fp_lb.tif")

3.2.3 Scenario 4

s4_mod_lb <- gbm.step(data = s4_md_lb, gbm.x = 2:7, gbm.y = 1, family = "bernoulli", tree.complexity = 5, learning.rate = 0.001, step.size = 1, bag.fraction = 0.5, prev.stratify = FALSE, verbose = FALSE, max.trees = 1000)
summary(s4_mod_lb)
# s4_ip_lb <- predict(s4_iv_lb, s4_mod_lb, type = "response", n.trees = s4_mod_lb$gbm.call$best.trees, filename = "output/habitat_pred/s4_fp_lb-000.tif")

# writeRaster(s4_ip_lb, "output/habitat_pred/s4_ip_lb.tif", overwrite = TRUE)

s4_ip_lb <- raster(x = "output/habitat_pred/s4_ip_lb.tif")

plot(s4_ip_lb)
registerDoMC(cores = 20)

s4_fp_lb <- foreach(i = seq_len(length(s4_fv_lb))) %dopar% {
  predict(s4_fv_lb[[i]],
          s4_mod_lb,
          type = "response",
          n.trees = s4_mod_lb$gbm.call$best.trees,
          filename = paste0("output/habitat_pred/s4_fp_lb-", sprintf("%03d", i), ".tif"),
          overwrite = TRUE)
}

s4_fp_lb <- stack(s4_fp_lb)
save(s4_fp_lb, file = "output/habitat_pred/s4_fp_lb")
writeRaster(s4_fp_lb, filename = "output/habitat_pred/s4_fp_lb.tif")

4 Population viability analysis

4.1 Greater Glider

gg_trans_mat <- matrix(c(0.00,0.00,0.25,
                         0.50,0.00,0.00,
                         0.00,0.85,0.85),
                       nrow = 3, ncol = 3, byrow = TRUE) # based on Possingham et al 1994
colnames(gg_trans_mat) <- rownames(gg_trans_mat) <- c('Newborn','Juvenile','Adult')

gg_stable_states <- abs( eigen(gg_trans_mat)$vectors[,1] / base::sum(eigen(gg_trans_mat)$vectors[,1]) ) 

4.1.1 Scenario 1

s1_hs_gg <- stack(s1_ip_gg, s1_fp_gg)

for(i in 1:51){
  s1_hs_gg[[i]][is.na(s1_hs_gg[[i]][])] <- 0
}

s1_hs_gg <- mask(s1_hs_gg, mask = ch_mask)
s1_hab_k_gg <- calc(s1_hs_gg[[1]], fun = function(x){if(is.na(x)) x else rbinom(prob = x, size = 3, n = 1)})

names(s1_hab_k_gg) <- "carryingCapacity"

s1_gg_popN <- stack(replicate(ncol(gg_trans_mat), s1_hab_k_gg))

s1_gg_popN <- s1_gg_popN*gg_stable_states

s1_gg_idx <- which(!is.na(s1_hs_gg[[1]][]) & s1_hs_gg[[1]][] < 0.95)

s1_gg_pop <- s1_gg_popN
s1_gg_pop[!is.na(s1_gg_pop)] <- 0
s1_gg_pop[[1]][sample(s1_gg_idx, 10000)] <- 1
s1_gg_pop[[2]][sample(s1_gg_idx, 10000)] <- 1
s1_gg_pop[[3]][sample(s1_gg_idx, 10000)] <- 1

s1_gg_pop <- s1_gg_pop*ch_mask

names(s1_gg_pop) <- colnames(gg_trans_mat)

s1_gg_TotpopN <- sum(cellStats(s1_gg_pop, 'sum', na.rm = TRUE)) # Get total population size to check sensible
s1_gg_init_pop_size <- sum(s1_gg_pop)
s1_gg_landscape <- landscape(population = s1_gg_pop,
                          suitability = s1_hs_gg,
                          carrying_capacity = s1_hab_k_gg)

s1_gg_pop_dynamics <- population_dynamics(change = growth(transition_matrix = gg_trans_mat,
                                                       global_stochasticity = 0.1),
                                       dispersal = fast_dispersal(
                                         dispersal_kernel = exponential_dispersal_kernel(
                                           distance_decay = 8000)),
                                       modification = NULL)
plan(sequential, workers = 1)
s1_gg_results_1_50 <- simulation(landscape = s1_gg_landscape,
                         population_dynamics = s1_gg_pop_dynamics,
                         habitat_dynamics = NULL,
                         timesteps = 50,
                         replicates = 1)


saveRDS(object = s1_gg_results_1_50, file = "output/pva_results/s1_gg_results_1_50.Rds")
plot(s1_gg_results_1_50)
plot(s1_gg_results_1_50[1], type = "raster", stages = 0, timesteps = c(1:5))

4.1.2 Scenario 3

s3_hs_gg <- stack(s3_ip_gg, s3_fp_gg)

for(i in 1:51){
  s3_hs_gg[[i]][is.na(s3_hs_gg[[i]][])] <- 0
}

s3_hs_gg <- mask(s3_hs_gg, mask = ch_mask)
s3_hab_k_gg <- calc(s3_hs_gg[[1]], fun = function(x){if(is.na(x)) x else rbinom(prob = x, size = 3, n = 1)})

names(s3_hab_k_gg) <- "carryingCapacity"

s3_gg_popN <- stack(replicate(ncol(gg_trans_mat), s3_hab_k_gg))

s3_gg_popN <- s3_gg_popN*gg_stable_states

s3_gg_idx <- which(!is.na(s3_hs_gg[[1]][]) & s3_hs_gg[[1]][] < 0.95)

s3_gg_pop <- s3_gg_popN
s3_gg_pop[!is.na(s3_gg_pop)] <- 0
s3_gg_pop[[1]][sample(s3_gg_idx, 10000)] <- 1
s3_gg_pop[[2]][sample(s3_gg_idx, 10000)] <- 1
s3_gg_pop[[3]][sample(s3_gg_idx, 10000)] <- 1

s3_gg_pop <- s3_gg_pop*ch_mask

names(s3_gg_pop) <- colnames(gg_trans_mat)

s3_gg_TotpopN <- sum(cellStats(s3_gg_pop, 'sum', na.rm = TRUE)) # Get total population size to check sensible
s3_gg_init_pop_size <- sum(s3_gg_pop)
s3_gg_landscape <- landscape(population = s3_gg_pop,
                          suitability = s3_hs_gg,
                          carrying_capacity = s3_hab_k_gg)

s3_gg_pop_dynamics <- population_dynamics(change = growth(transition_matrix = gg_trans_mat,
                                                       global_stochasticity = 0.1),
                                       dispersal = fast_dispersal(
                                         dispersal_kernel = exponential_dispersal_kernel(
                                           distance_decay = 8000)),
                                       modification = NULL)
plan(sequential, workers = 1)
s3_gg_results_1_50 <- simulation(landscape = s3_gg_landscape,
                         population_dynamics = s3_gg_pop_dynamics,
                         habitat_dynamics = NULL,
                         timesteps = 50,
                         replicates = 1)


saveRDS(object = s3_gg_results_1_50, file = "output/pva_results/s3_gg_results_1_50.Rds")
plot(s3_gg_results_1_50)
plot(s3_gg_results_1_50[1], type = "raster", stages = 0, timesteps = c(1:5))

4.1.3 Scenario 4

s4_hs_gg <- stack(s4_ip_gg, s4_fp_gg)

for(i in 1:51){
  s4_hs_gg[[i]][is.na(s4_hs_gg[[i]][])] <- 0
}

s4_hs_gg <- mask(s4_hs_gg, mask = ch_mask)
s4_hab_k_gg <- calc(s4_hs_gg[[1]], fun = function(x){if(is.na(x)) x else rbinom(prob = x, size = 3, n = 1)})

names(s4_hab_k_gg) <- "carryingCapacity"

s4_gg_popN <- stack(replicate(ncol(gg_trans_mat), s4_hab_k_gg))

s4_gg_popN <- s4_gg_popN*gg_stable_states

s4_gg_idx <- which(!is.na(s4_hs_gg[[1]][]) & s4_hs_gg[[1]][] < 0.95)

s4_gg_pop <- s4_gg_popN
s4_gg_pop[!is.na(s4_gg_pop)] <- 0
s4_gg_pop[[1]][sample(s4_gg_idx, 10000)] <- 1
s4_gg_pop[[2]][sample(s4_gg_idx, 10000)] <- 1
s4_gg_pop[[3]][sample(s4_gg_idx, 10000)] <- 1

s4_gg_pop <- s4_gg_pop*ch_mask

names(s4_gg_pop) <- colnames(gg_trans_mat)

s4_gg_TotpopN <- sum(cellStats(s4_gg_pop, 'sum', na.rm = TRUE)) # Get total population size to check sensible
s4_gg_init_pop_size <- sum(s4_gg_pop)
s4_gg_landscape <- landscape(population = s4_gg_pop,
                          suitability = s4_hs_gg,
                          carrying_capacity = s4_hab_k_gg)

s4_gg_pop_dynamics <- population_dynamics(change = growth(transition_matrix = gg_trans_mat,
                                                       global_stochasticity = 0.1),
                                       dispersal = fast_dispersal(
                                         dispersal_kernel = exponential_dispersal_kernel(
                                           distance_decay = 8000)),
                                       modification = NULL)
plan(sequential, workers = 1)
s4_gg_results_1_50 <- simulation(landscape = s4_gg_landscape,
                         population_dynamics = s4_gg_pop_dynamics,
                         habitat_dynamics = NULL,
                         timesteps = 50,
                         replicates = 1)


saveRDS(object = s4_gg_results_1_50, file = "output/pva_results/s4_gg_results_1_50.Rds")
plot(s4_gg_results_1_50)
plot(s4_gg_results_1_50[1], type = "raster", stages = 0, timesteps = c(1:5))

4.2 Leadbeater’s Possum

lb_trans_mat <- matrix(c(0.00, 0.00, 1.10,
                         0.59, 0.00, 0.00,
                         0.00, 0.59, 0.79),
                       nrow = 3, ncol = 3, byrow = TRUE) 
colnames(lb_trans_mat) <- rownames(lb_trans_mat) <- c('Newborn','Juvenile','Adult')

lb_stable_states <- abs( eigen(lb_trans_mat)$vectors[,1] / base::sum(eigen(lb_trans_mat)$vectors[,1]) ) 

4.2.1 Scenario 1

s1_hs_lb <- stack(s1_ip_lb, s1_fp_lb)

for(i in 1:51){
  s1_hs_lb[[i]][is.na(s1_hs_lb[[i]][])] <- 0
}

s1_hs_lb <- mask(s1_hs_lb, mask = ch_mask)
s1_hab_k_lb <- calc(s1_hs_lb[[1]], fun = function(x){if(is.na(x)) x else rbinom(prob = x, size = 3, n = 1)})

names(s1_hab_k_lb) <- "carryingCapacity"

s1_lb_popN <- stack(replicate(ncol(lb_trans_mat), s1_hab_k_lb))

s1_lb_popN <- s1_lb_popN*lb_stable_states

s1_lb_idx <- which(!is.na(s1_hs_lb[[1]][]) & s1_hs_lb[[1]][] < 0.95)

s1_lb_pop <- s1_lb_popN
s1_lb_pop[!is.na(s1_lb_pop)] <- 0
s1_lb_pop[[1]][sample(s1_lb_idx, 3000)] <- 1
s1_lb_pop[[2]][sample(s1_lb_idx, 3000)] <- 1
s1_lb_pop[[3]][sample(s1_lb_idx, 3000)] <- 1

s1_lb_pop <- s1_lb_pop*ch_mask

names(s1_lb_pop) <- colnames(lb_trans_mat)

s1_lb_TotpopN <- sum(cellStats(s1_lb_pop, 'sum', na.rm = TRUE)) # Get total population size to check sensible
s1_lb_init_pop_size <- sum(s1_lb_pop)
s1_lb_landscape <- landscape(population = s1_lb_pop,
                          suitability = s1_hs_lb,
                          carrying_capacity = s1_hab_k_lb)

s1_lb_pop_dynamics <- population_dynamics(change = growth(transition_matrix = lb_trans_mat,
                                                       global_stochasticity = 0.3),
                                       dispersal = fast_dispersal(
                                         dispersal_kernel = exponential_dispersal_kernel(
                                           distance_decay = 2000)),
                                       modification = NULL)
plan(sequential, workers = 1)
s1_lb_results_1_50 <- simulation(landscape = s1_lb_landscape,
                         population_dynamics = s1_lb_pop_dynamics,
                         habitat_dynamics = NULL,
                         timesteps = 50,
                         replicates = 1)


saveRDS(object = s1_lb_results_1_50, file = "output/pva_results/s1_lb_results_1_50.Rds")
plot(s1_lb_results_1_50)
plot(s1_lb_results_1_50[1], type = "raster", stages = 0, timesteps = c(1:5))

4.2.2 Scenario 3

s3_hs_lb <- stack(s3_ip_lb, s3_fp_lb)

for(i in 1:51){
  s3_hs_lb[[i]][is.na(s3_hs_lb[[i]][])] <- 0
}

s3_hs_lb <- mask(s3_hs_lb, mask = ch_mask)
s3_hab_k_lb <- calc(s3_hs_lb[[1]], fun = function(x){if(is.na(x)) x else rbinom(prob = x, size = 3, n = 1)})

names(s3_hab_k_lb) <- "carryingCapacity"

s3_lb_popN <- stack(replicate(ncol(lb_trans_mat), s3_hab_k_lb))

s3_lb_popN <- s3_lb_popN*lb_stable_states

s3_lb_idx <- which(!is.na(s3_hs_lb[[1]][]) & s3_hs_lb[[1]][] < 0.95)

s3_lb_pop <- s3_lb_popN
s3_lb_pop[!is.na(s3_lb_pop)] <- 0
s3_lb_pop[[1]][sample(s3_lb_idx, 3000)] <- 1
s3_lb_pop[[2]][sample(s3_lb_idx, 3000)] <- 1
s3_lb_pop[[3]][sample(s3_lb_idx, 3000)] <- 1

s3_lb_pop <- s3_lb_pop*ch_mask

names(s3_lb_pop) <- colnames(lb_trans_mat)

s3_lb_TotpopN <- sum(cellStats(s3_lb_pop, 'sum', na.rm = TRUE)) # Get total population size to check sensible
s3_lb_init_pop_size <- sum(s3_lb_pop)
s3_lb_landscape <- landscape(population = s3_lb_pop,
                          suitability = s3_hs_lb,
                          carrying_capacity = s3_hab_k_lb)

s3_lb_pop_dynamics <- population_dynamics(change = growth(transition_matrix = lb_trans_mat,
                                                       global_stochasticity = 0.1),
                                       dispersal = fast_dispersal(
                                         dispersal_kernel = exponential_dispersal_kernel(
                                           distance_decay = 8000)),
                                       modification = NULL)
plan(sequential, workers = 1)
s3_lb_results_1_50 <- simulation(landscape = s3_lb_landscape,
                         population_dynamics = s3_lb_pop_dynamics,
                         habitat_dynamics = NULL,
                         timesteps = 50,
                         replicates = 1)


saveRDS(object = s3_lb_results_1_50, file = "output/pva_results/s3_lb_results_1_50.Rds")
plot(s3_lb_results_1_50)
plot(s3_lb_results_1_50[1], type = "raster", stages = 0, timesteps = c(1:5))

4.2.3 Scenario 4

s4_hs_lb <- stack(s4_ip_lb, s4_fp_lb)

for(i in 1:51){
  s4_hs_lb[[i]][is.na(s4_hs_lb[[i]][])] <- 0
}

s4_hs_lb <- mask(s4_hs_lb, mask = ch_mask)
s4_hab_k_lb <- calc(s4_hs_lb[[1]], fun = function(x){if(is.na(x)) x else rbinom(prob = x, size = 3, n = 1)})

names(s4_hab_k_lb) <- "carryingCapacity"

s4_lb_popN <- stack(replicate(ncol(lb_trans_mat), s4_hab_k_lb))

s4_lb_popN <- s4_lb_popN*lb_stable_states

s4_lb_idx <- which(!is.na(s4_hs_lb[[1]][]) & s4_hs_lb[[1]][] < 0.95)

s4_lb_pop <- s4_lb_popN
s4_lb_pop[!is.na(s4_lb_pop)] <- 0
s4_lb_pop[[1]][sample(s4_lb_idx, 3000)] <- 1
s4_lb_pop[[2]][sample(s4_lb_idx, 3000)] <- 1
s4_lb_pop[[3]][sample(s4_lb_idx, 3000)] <- 1

s4_lb_pop <- s4_lb_pop*ch_mask

names(s4_lb_pop) <- colnames(lb_trans_mat)

s4_lb_TotpopN <- sum(cellStats(s4_lb_pop, 'sum', na.rm = TRUE)) # Get total population size to check sensible
s4_lb_init_pop_size <- sum(s4_lb_pop)
s4_lb_landscape <- landscape(population = s4_lb_pop,
                          suitability = s4_hs_lb,
                          carrying_capacity = s4_hab_k_lb)

s4_lb_pop_dynamics <- population_dynamics(change = growth(transition_matrix = lb_trans_mat,
                                                       global_stochasticity = 0.1),
                                       dispersal = fast_dispersal(
                                         dispersal_kernel = exponential_dispersal_kernel(
                                           distance_decay = 8000)),
                                       modification = NULL)
plan(sequential, workers = 1)
s4_lb_results_1_50 <- simulation(landscape = s4_lb_landscape,
                         population_dynamics = s4_lb_pop_dynamics,
                         habitat_dynamics = NULL,
                         timesteps = 50,
                         replicates = 1)


saveRDS(object = s4_lb_results_1_50, file = "output/pva_results/s4_lb_results_1_50.Rds")
plot(s4_lb_results_1_50)
plot(s4_lb_results_1_50[1], type = "raster", stages = 0, timesteps = c(1:5))
LS0tCnRpdGxlOiAiVmljdG9yaWFuIEZvcmVzdCBGdXR1cmVzIFBvcHVsYXRpb24gVmFiaWxpdHkgQW5hbHlzaXM6IENlbnRyYWwgSGlnaGxhbmRzIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgdG9jOiB5ZXMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQphdXRob3I6IEdFIFJ5YW4KZGF0ZTogMjAxOS0wOC0wNQotLS0KCiMgUHJvamVjdCBzZXR1cAoKIyMjIFBhY2thZ2VzCkluc3RhbGwgcGFja2FnZXMgaWYgbmVjZXNzYXJ5LiBMaXN0ZWQgYXJlIGluc3RhbGxlcnMgZm9yIHBhY2thZ2VzIG5vdCBvbiBDUkFOIGFuZCB0aGUgZGV2bG9wbWVudCAobW9zdCB1cC10by1kYXRlKSB2ZXJzaW9uIG9mIFNURVBTLgpgYGB7ciBpbnN0YWxsIHBhY2thZ2VzfQojIGxpYnJhcnkoZGV2dG9vbHMpCiMgaW5zdGFsbF9naXRodWIoInN0ZXBzLWRldi9zdGVwcyIpCiMgaW5zdGFsbF9naXRodWIoInNtd2luZGVja2VyL2dkYWx0b29scyIpCmBgYAoKTG9hZCBwYWNrYWdlcwpgYGB7ciBwYWNrYWdlc30KbGlicmFyeShyYXN0ZXIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHNmKQpsaWJyYXJ5KHJnZGFsKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHJlYWR4bCkKbGlicmFyeShnZ3Bsb3QyKQpsaWJyYXJ5KGx1YnJpZGF0ZSkKbGlicmFyeShtYWdyaXR0cikKbGlicmFyeSh0aWR5cikKbGlicmFyeShmb3JlYWNoKQpsaWJyYXJ5KGRvTUMpCmxpYnJhcnkoZnV0dXJlKQpsaWJyYXJ5KGZ1dHVyZS5hcHBseSkKbGlicmFyeSh0aWR5cikKbGlicmFyeShkaXNtbykKbGlicmFyeShnYm0pCmxpYnJhcnkoc3RlcHMpCmxpYnJhcnkoZ2RhbHRvb2xzKQpgYGAKCiMjIyBGdW5jdGlvbnMKYGBge3IgZnVuY3Rpb25zfQpzb3VyY2UoZmlsZSA9ICJSL2Z1bmN0aW9ucy9wZy5zZi5SIikKc291cmNlKGZpbGUgPSAiUi9mdW5jdGlvbnMvcGcucGEuUiIpCnNvdXJjZShmaWxlID0gIlIvZnVuY3Rpb25zL3JlYWQudmJhLlIiKQpzb3VyY2UoZmlsZSA9ICJSL2Z1bmN0aW9ucy9wcm9jLnZiYS5SIikKc291cmNlKGZpbGUgPSAiUi9mdW5jdGlvbnMvZ2V0LmxhbmRpcy52YXJzLlIiKQpzb3VyY2UoZmlsZSA9ICJSL2Z1bmN0aW9ucy9yYXNjYy5SIikKc291cmNlKGZpbGUgPSAiUi9mdW5jdGlvbnMvcmVhZC5tdWx0aS5saW5lLmhlYWRlci5SIikKc291cmNlKGZpbGUgPSAiUi9mdW5jdGlvbnMvaW50ZXJwb2xhdGUuY2xpbWRhdC5SIikKc291cmNlKGZpbGUgPSAiUi9mdW5jdGlvbnMvZ2V0LnJzdC5wcm9wLlIiKQpzb3VyY2UoZmlsZSA9ICJSL2Z1bmN0aW9ucy9nZXQucnN0LmRhdC5SIikKYGBgCgojIyMgUGF0aHMKYGBge3IgcGF0aHN9CnByb2pfcGF0aCA8LSAiL2hvbWUvbGFuZGlzL3Jmc3QvIgojIHByb2pfcGF0aCA8LSAiRDovVXNlcnMvcnlhbi9Ecm9wYm94L1dvcmsvUkZBX1NURVBTL3Jmc3QvIgpgYGAKCgojIFByZXBhcmUgdmFyaWFibGVzCgojIyBBbmFseXNpcyBwYXJhbWV0ZXJzCgojIyMgVGltZXN0ZXBzCmBgYHtyIG50aW1lc3RlcHN9Cm50aW1lc3RlcHMgPC0gNTAKYGBgCgpgYGB7ciBuY29yZXN9Cm5jb3JlcyA8LSAyMApgYGAKCgoKIyMgR2VvZ3JhcGhpYyBkYXRhCgojIyMgTGFuZHNjYXBlClNldCB1cCBiYXNlIGxhbmRzY2FwZSBsYXllcgpgYGB7ciBjaF9yc3R9CmNoX3JzdCA8LSByYXN0ZXIoeCA9ICJkYXRhL2dyaWRzL2Vjb192MTIuaW1nIikgJVQ+JQogIHBsb3QKYGBgCgpgYGB7ciBwcm9qIGV4dCByZXN9CmNoX3Byb2ogPC0gY2hfcnN0QGNycwpjaF9leHRlbnQgPC0gZXh0ZW50KGNoX3JzdCkKY2hfcmVzIDwtIHJlcyhjaF9yc3QpCmBgYAoKIyMjIEJvdW5kYXJpZXMKYGBge3IgcmZhfQpyZmEgPC0gcmVhZF9zZigiZGF0YS9zaGFwZWZpbGVzL1JGQS8iKSU+JQogIHN0X3RyYW5zZm9ybShjcnMgPSBjaF9wcm9qKQpyZmEKYGBgCgpgYGB7ciBwbG90IHJmYX0KcGcuc2YocmZhKQpgYGAKCmBgYHtyIGNoX3JmYX0KY2hfcmZhIDwtIHJmYVtyZmEkTkFNRT09ICJDRU5UUkFMIEhJR0hMQU5EUyIsXSAKCmNoX3JmYQpgYGAKCmBgYHtyIHBsb3QgY2hfcmZhfQpwZy5zZihjaF9yZmEpCmBgYAoKCmBgYHtyIGNoX21hc2t9CmNoX21hc2sgPC0gcmFzdGVyaXplKGNoX3JmYSwgY2hfcnN0LCBmaWVsZCA9IDEsIGZpbGVuYW1lID0gIi4vb3V0cHV0L2xhbmRzY2FwZV92YXJzL2NoX21hc2suZ3JkIiwgb3ZlcndyaXRlID0gVFJVRSkgCgpjaF9tYXNrW2NoX3JzdCA9PSAxMzJdIDwtIE5BICMgcmVtb3ZlcyBsYWtlIGFyZWFzIGZyb20gaGFiaXRhdAoKcGxvdChjaF9tYXNrKQpgYGAKKlRoaW5rIGNhcmVmdWxseSBhYm91dCB1c2luZyB0aGlzIGxheWVyIGFzIHByb2plY3Rpb25zIGFyZSBmb3Igem9uZSA1NSwgc28gZGlzdG9ydHMgd2VzdCBvZiB0aGUgc3RhdGUqCmBgYHtyIHZpY3RvcmlhfQp2aWN0b3JpYSA8LSByZWFkX3NmKCJkYXRhL3NoYXBlZmlsZXMvdmljc3RhdGVwb2x5Z29uLyIpICU+JQogICBzdF90cmFuc2Zvcm0oY3JzID0gY2hfcHJvaikKYGBgCgoKCgojIyBPY2N1cnJlbmNlIGRhdGEKCmBgYHtyIHBzZXVkb19hYnN9CnBzZXVkb19hYnMgPC0gcmVhZF9zZigiZGF0YS9zaGFwZWZpbGVzL3BzZXVkb19hYnNlbmNlcy9wc2V1ZG9fYWJzZW5jZXMuc2hwIiklPiUKICBzdF90cmFuc2Zvcm0oY3JzID0gc3RfY3JzKGNoX3JzdCkpICU+JQogIG11dGF0ZShQQSA9IDApICU+JQogIHNlbGVjdChQQSwgZ2VvbWV0cnkpICU+JQogIHN0X3ptKGRyb3AgPSBUUlVFKQoKcHNldWRvX2FicwpgYGAKCgojIyMgR0cgT2NjdXJyZW5jZSBkYXRhClJlYWQgaW4gZGF0YQpgYGB7ciBnZ19hcml9CmdnX2FyaSA8LSByZWFkX2V4Y2VsKHBhdGggPSAiZGF0YS90YWJ1bGFyL0JvQV9TQl9Db21iaW5lZF9WQkFfdXBsb2FkX3Y0LnhscyIpICU+JQogIGRwbHlyOjpzZWxlY3QoLXN0YXJ0c193aXRoKCJsZWF2ZSIpKSAlPiUKICByZW5hbWUoImxvbiIgPSBgWC1jb29yZGluYXRlIChlYXN0aW5nIG9yIGxvbmdpdHVkZSlgLCAibGF0IiA9IGBZLWNvb3JkaW5hdGUgKG5vcnRoaW5nIG9yIGxhdGl0dWRlKWApICU+JQogICBmaWxsKGxvbiwgbGF0LCAuZGlyZWN0aW9uID0gImRvd24iKSAlPiUKICBmaWx0ZXIoYFRheG9uIE5hbWVgID09ICJNaXNjIFRhcmdldCB0YXhhIG5vdCBmb3VuZCIpICU+JQogIHNlbGVjdChsb24sIGxhdCkgJT4lCiAgbXV0YXRlKFBBID0gMCkgJT4lCiAgc3RfYXNfc2YoY29vcmRzID0gYygibG9uIiwgImxhdCIpLCBjcnMgPSBzdF9jcnMoMjgzNTUpKSAlPiUKICBzdF90cmFuc2Zvcm0oY3JzID0gc3RfY3JzKGNoX3JzdCkpCgpnZ19hcmkKYGBgCgpgYGB7ciBnZ192YmF9CmdnX3ZiYSA8LSBwcm9jLnZiYSgiZGF0YS90YWJ1bGFyL3ZiYV9nZ19hbGxfMjAxOTA1MDkuY3N2IiwgcHJvamVjdC5jcnMgPSBjaF9wcm9qKQoKZ2dfdmJhCmBgYAoKYGBge3IgZ2dfcGFfYWxsfQpnZ19wYV9hbGwgPC0gZ2dfdmJhICU+JQogIHJiaW5kKGdnX2FyaSkKCmdnX3BhX2FsbApgYGAKCmBgYHtyIHBsb3RfZ2dfcGFfYWxsfQpwbG90X2dnX3BhX2FsbCA8LSBwZy5wYShnZ19wYV9hbGwsIGNoX3JmYSkgKwogIGdlb21fc2YoZGF0YSA9IHZpY3RvcmlhLCBmaWxsID0gTkEpCgpwbG90X2dnX3BhX2FsbApgYGAKCmBgYHtyIGdnX3BhX2NofQpnZ19wYV9jaCA8LSBnZ19wYV9hbGxbY2hfcmZhLF0KZ2dfcGFfY2gKYGBgCgpgYGB7ciBnZ19wYV9jaF9wc2FifQpnZ19wYV9jaF9wc2FiIDwtIGdnX3BhX2NoICU+JQogIHJiaW5kKHBzZXVkb19hYnMpCmBgYAoKCmBgYHtyIHdyaXRlIGdnX3BhX2NofQpzdF93cml0ZShnZ19wYV9jaCwgIm91dHB1dC9zaGFwZWZpbGVzL3BhL2NoL2dnX3BhX2NoLnNocCIsIGRlbGV0ZV9sYXllciA9IFRSVUUpCnN0X3dyaXRlKGdnX3BhX2NoX3BzYWIsICJvdXRwdXQvc2hhcGVmaWxlcy9wYS9jaC9nZ19wYV9jaF9wc2FiLnNocCIsIGRlbGV0ZV9sYXllciA9IFRSVUUpCmBgYAoKCmBgYHtyIHBnX2dnX3BhX2NofQpwZ19nZ19wYV9jaCA8LSBwZy5wYShnZ19wYV9jaCAlPiUgbXV0YXRlKHBzZXVkb19hYnMgPSAidmJhIikgJT4lIHJiaW5kKHBzZXVkb19hYnMgJT4lIG11dGF0ZShwc2V1ZG9fYWJzID0gInBzZXVkb19hYnNlbmNlcyIpKSwgY2hfcmZhKSArCiAgZmFjZXRfZ3JpZCgufnBzZXVkb19hYnMpCgpwZ19nZ19wYV9jaApgYGAKCiMjIyBMQlAgT2NjdXJyZW5jZSBkYXRhCmBgYHtyIHJlYWQgbGIgb2NjfQpsYl9wYV9hbGwgPC0gcHJvYy52YmEoImRhdGEvdGFidWxhci92YmFfbGJfYWxsXzIwMTkwNTA5LmNzdiIsIHByb2plY3QuY3JzID0gY2hfcHJvaikKYGBgCgpgYGB7ciBwbG90X2xiX3BhX2FsbH0KcGxvdF9sYl9wYV9hbGwgPC0gcGcucGEobGJfcGFfYWxsLCBjaF9yZmEpICsKICBnZW9tX3NmKGRhdGEgPSB2aWN0b3JpYSwgZmlsbCA9IE5BKQoKcGxvdF9sYl9wYV9hbGwKYGBgCgpgYGB7ciBsYl9wYV9jaH0KbGJfcGFfY2ggPC0gbGJfcGFfYWxsW2NoX3JmYSxdCmxiX3BhX2NoCmBgYAoKYGBge3IgbGJfcGFfY2hfcHNhYn0KbGJfcGFfY2hfcHNhYiA8LSBsYl9wYV9jaCAlPiUKICByYmluZChwc2V1ZG9fYWJzKQpgYGAKCgpgYGB7ciB3cml0ZSBsYnBfcGFfY2h9CnN0X3dyaXRlKGxiX3BhX2NoLCAib3V0cHV0L3NoYXBlZmlsZXMvcGEvY2gvbGJfcGFfY2guc2hwIiwgZGVsZXRlX2xheWVyID0gVFJVRSkKc3Rfd3JpdGUobGJfcGFfY2hfcHNhYiwgIm91dHB1dC9zaGFwZWZpbGVzL3BhL2NoL2xiX3BhX2NoX3BzYWIuc2hwIiwgZGVsZXRlX2xheWVyID0gVFJVRSkKYGBgCgoKYGBge3IgcGdfbGJfcGFfY2h9CnBnX2xiX3BhX2NoIDwtIHBnLnBhKGxiX3BhX2NoICU+JSBtdXRhdGUocHNldWRvX2FicyA9ICJ2YmEiKSAlPiUgcmJpbmQocHNldWRvX2FicyAlPiUgbXV0YXRlKHBzZXVkb19hYnMgPSAicHNldWRvX2Fic2VuY2VzIikpLCBjaF9yZmEpICsKICBmYWNldF9ncmlkKC5+cHNldWRvX2FicykKCnBnX2xiX3BhX2NoCmBgYAoKYGBge3Igc2F2ZSBpbWFnZSBvY2N1fQpzYXZlLmltYWdlKCJvdXRwdXQvc2Vzc2lvbl9pbWFnZXMvbGFuZHNjYXBlLW9jY3VwYW5jeS5SRGF0YSIpCmBgYAoKYGBge3IgbG9hZCBpbWFnZSBvY2N1fQojbG9hZChmaWxlID0gIm91dHB1dC9zZXNzaW9uX2ltYWdlcy9sYW5kc2NhcGUtb2NjdXBhbmN5LlJEYXRhIikKYGBgCgoKIyMgTGFuZGlzIG91dHB1dAoKIyMjIFNjZW5hcmlvIDE6IEN1cnJlbnQgcGxhbm5lZCBidXJuaW5nLCBjdXJyZW50IHRpbWJlciBoYXJ2ZXN0aW5nLCBjbGltYXRlIGNoYW5nZSB1bmRlciBSQ1AgNC41LCBjdXJyZW50IGJ1c2hmaXJlIHJlZ2ltZSAoQnVpc25lc3MgYXMgdXN1YWwpCmBgYHtyIHMxX3ZhcnNfbGFuZGlzfQpzMV92YXJzX2xhbmRpcyA8LSBnZXQubGFuZGlzLnZhcnMoCiAgc2NuX3BhdGggPSAifi9sYW5kaXNfY2hfczFfcGItdGgtY2NfNTAvIiwKICBwcm9qX3BhdGggPSBwcm9qX3BhdGgsCiAgb3V0X3BhdGggPSAiL291dHB1dC9oYWJpdGF0X3ZhcnMvIiwKICBzY25faWQgPSAiczEiLAogIHByb2pfbWFzayA9IGNoX21hc2ssCiAgdGltZXN0ZXBzID0gbnRpbWVzdGVwcywKICBjb3JlcyA9IG5jb3JlcwogICkKYGBgCgpgYGB7ciBwbG90IHMxX3ZhcnNfbGFuZGlzIGluaXRpYWx9CnBsb3QoczFfdmFyc19sYW5kaXNbWzFdXSkKYGBgCgpgYGB7ciBwbG90IHMxX3ZhcnNfbGFuZGlzIGxhc3R9CnBsb3QoczFfdmFyc19sYW5kaXNbW250aW1lc3RlcHMgKyAxXV0pCmBgYAoKCmBgYHtyIHMxX3ZhcnNfbGFuZGlzIHNhdmUgbG9hZH0Kc2F2ZShzMV92YXJzX2xhbmRpcywgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3MxX3ZhcnNfbGFuZGlzIikKCiMgbG9hZChmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczFfdmFyc19sYW5kaXNfZnV0IikKYGBgCgoKIyMjIFNjZW5hcmlvIDI6IEN1cnJlbnQgcGxhbm5lZCBidXJuaW5nLCBjdXJyZW50IHRpbWJlciBoYXJ2ZXN0aW5nLCBjbGltYXRlIGNoYW5nZSB1bmRlciBSQ1AgOC41LCBpbmNyZWF0cmVkIGJ1c2hmaXJlIHJlZ2ltZQoKCiMjIyBTY2VuYXJpbyAzOiBDdXJyZW50IHBsYW5uZWQgYnVybmluZywgY3VycmVudCB0aW1iZXIgaGFydmVzdGluZywgbm8gY2xpbWF0ZSBjaGFuZ2UsIGN1cnJlbnQgYnVzaGZpcmUgcmVnaW1lCmBgYHtyIHMzX3ZhcnNfbGFuZGlzfQpzM192YXJzX2xhbmRpcyA8LSBnZXQubGFuZGlzLnZhcnMoCiAgc2NuX3BhdGggPSAifi9sYW5kaXNfY2hfczNfcGItdGgtY2MwXzUwLyIsCiAgcHJval9wYXRoID0gcHJval9wYXRoLAogIG91dF9wYXRoID0gIi9vdXRwdXQvaGFiaXRhdF92YXJzLyIsCiAgc2NuX2lkID0gInMzIiwKICBwcm9qX21hc2sgPSBjaF9tYXNrLAogIHRpbWVzdGVwcyA9IG50aW1lc3RlcHMsCiAgY29yZXMgPSBuY29yZXMKICApCmBgYAoKYGBge3IgcGxvdCBzM192YXJzX2xhbmRpcyBpbml0aWFsfQpwbG90KHMzX3ZhcnNfbGFuZGlzW1sxXV0pCmBgYAoKYGBge3IgcGxvdCBzM192YXJzX2xhbmRpcyBsYXN0fQpwbG90KHMzX3ZhcnNfbGFuZGlzW1tudGltZXN0ZXBzICsgMV1dKQpgYGAKCgpgYGB7ciBzM192YXJzX2xhbmRpcyBzYXZlIGxvYWR9CnNhdmUoczNfdmFyc19sYW5kaXMsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zM192YXJzX2xhbmRpcyIpCgojIGxvYWQoZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3MzX3ZhcnNfbGFuZGlzX2Z1dCIpCmBgYAoKIyMjIFNjZW5hcmlvIDQ6IEN1cnJlbnQgcGxhbm5lZCBidXJuaW5nLCBubyBoYXJ2ZXN0aW5nLCBjbGltYXRlIGNoYW5nZSB1bmRlciBSQ1AgNC41LCBjdXJyZW50IGJ1c2hmaXJlIHJlZ2ltZQpgYGB7ciBzNF92YXJzX2xhbmRpc30KczRfdmFyc19sYW5kaXMgPC0gZ2V0LmxhbmRpcy52YXJzKAogIHNjbl9wYXRoID0gIn4vbGFuZGlzX2NoX3M0X3BiLXRoMC1jY181MC8iLAogIHByb2pfcGF0aCA9IHByb2pfcGF0aCwKICBvdXRfcGF0aCA9ICIvb3V0cHV0L2hhYml0YXRfdmFycy8iLAogIHNjbl9pZCA9ICJzNCIsCiAgcHJval9tYXNrID0gY2hfbWFzaywKICB0aW1lc3RlcHMgPSBudGltZXN0ZXBzLAogIGNvcmVzID0gbmNvcmVzLAogIGhhcnZlc3RfdGltYmVyID0gRkFMU0UKICApCmBgYAoKYGBge3IgcGxvdCBzNF92YXJzX2xhbmRpcyBpbml0aWFsfQpwbG90KHM0X3ZhcnNfbGFuZGlzW1sxXV0pCmBgYAoKYGBge3IgcGxvdCBzNF92YXJzX2xhbmRpcyBsYXN0fQpwbG90KHM0X3ZhcnNfbGFuZGlzW1tudGltZXN0ZXBzICsgMV1dKQpgYGAKCgpgYGB7ciBzNF92YXJzX2xhbmRpcyBzYXZlIGxvYWR9CnNhdmUoczRfdmFyc19sYW5kaXMsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zNF92YXJzX2xhbmRpcyIpCgojIGxvYWQoZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3M0X3ZhcnNfbGFuZGlzX2Z1dCIpCmBgYAoKIyMgQVJJIERhdGEKCiMjIyBBbmlzb3Ryb25pYyBoZWF0aW5nIHggcnVnZ2VkbmVzcwpgYGB7ciBhaHJ9CmFociA8LXJhc3Rlcih4ID0gImRhdGEvZ3JpZHMvRW52X2NvdmFyaWF0ZXNfbm9DbGltYXRlX1ZpY0dyaWQ5NC9Bbmlzb3Ryb3BoaWNfSGVhdGluZ19SdWdnZWRuZXNzIikgJT4lCiAgcHJvamVjdFJhc3Rlcih0byA9IGNoX21hc2spICU+JQogIG1hc2sobWFzayA9IGNoX21hc2ssIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvYXJpX2Foci5ncmQiKSAlVD4lCiAgcGxvdApgYGAKCiMjIyBMb2cgdmVydGljaWNhbCBkaXN0YW5jZSBhbGwgd2V0bGFuZHMKYGBge3IgbHZkYXd9Cmx2ZGF3IDwtIHJhc3Rlcih4ID0gImRhdGEvZ3JpZHMvRW52X2NvdmFyaWF0ZXNfbm9DbGltYXRlX1ZpY0dyaWQ5NC9sb2dfdmVydGljYWxfZGlzdGFuY2VfYWxsX3dldGxhbmRzX3NlcHQyMDEyIikgJT4lCiAgcHJvamVjdFJhc3Rlcih0byA9IGNoX21hc2spICU+JQogIG1hc2sobWFzayA9IGNoX21hc2ssIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvYXJpX2x2ZGF3LmdyZCIpICVUPiUKICBwbG90CmBgYAojIyMgTG9nIHZlcnRpY2FsIGRpc3RhbmNlIG1ham9yIHN0cmVhbXMKYGBge3IgbHZkbWF9Cmx2ZG1hIDwtIHJhc3Rlcih4ID0gImRhdGEvZ3JpZHMvRW52X2NvdmFyaWF0ZXNfbm9DbGltYXRlX1ZpY0dyaWQ5NC9sb2dfdmVydGljYWxfZGlzdGFuY2VfbWFqb3Jfc3RyZWFtc19zZXB0MjAxMiIpICU+JQogIHByb2plY3RSYXN0ZXIodG8gPSBjaF9tYXNrKSAlPiUKICBtYXNrKG1hc2sgPSBjaF9tYXNrLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL2FyaV9sdmRtYS5ncmQiKSAlVD4lCiAgcGxvdApgYGAKIyMjIExvZyB2ZXJ0aWNhbCBkaXN0YW5jZSBtaW5vciBzdHJlYW1zCmBgYHtyIGx2ZG1pfQpsdmRtaSA8LSByYXN0ZXIoeCA9ICJkYXRhL2dyaWRzL0Vudl9jb3ZhcmlhdGVzX25vQ2xpbWF0ZV9WaWNHcmlkOTQvbG9nX3ZlcnRpY2FsX2Rpc3RhbmNlX21pbm9yX3N0cmVhbXNfc2VwdDIwMTIiKSAlPiUKICBwcm9qZWN0UmFzdGVyKHRvID0gY2hfbWFzaykgJT4lCiAgbWFzayhtYXNrID0gY2hfbWFzaywgZmlsZW5hbWUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9hcmlfbHZkbWkuZ3JkIikgJVQ+JQogIHBsb3QKYGBgCiMjIyBMb2cgdmVydGljYWwgZGlzdGFuY2Ugc2FsaW5lIHdldGxhbmRzCmBgYHtyIGx2ZHN3fQpsdmRzdyA8LSByYXN0ZXIoeCA9ICJkYXRhL2dyaWRzL0Vudl9jb3ZhcmlhdGVzX25vQ2xpbWF0ZV9WaWNHcmlkOTQvbG9nX3ZlcnRpY2FsX2Rpc3RhbmNlX3NhbGluZV93ZXRsYW5kc19zZXB0MjAxMiIpICU+JQogIHByb2plY3RSYXN0ZXIodG8gPSBjaF9tYXNrKSAlPiUKICBtYXNrKG1hc2sgPSBjaF9tYXNrLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL2FyaV9sdmRzdy5ncmQiKSAlVD4lCiAgcGxvdApgYGAKIyMjIFJlbGF0aXZlIGFubnVhbCBpbnNvbGF0aW9uCmBgYHtyIHJhaX0KcmFpIDwtIHJhc3Rlcih4ID0gImRhdGEvZ3JpZHMvRW52X2NvdmFyaWF0ZXNfbm9DbGltYXRlX1ZpY0dyaWQ5NC9yZWxhdGl2ZV9hbm51YWxfaW5zb2xhdGlvbl9zZXB0MjAxMiIpICU+JQogIHByb2plY3RSYXN0ZXIodG8gPSBjaF9tYXNrKSAlPiUKICBtYXNrKG1hc2sgPSBjaF9tYXNrLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL2FyaV9yYWkuZ3JkIikgJVQ+JQogIHBsb3QKYGBgCiMjIyBUaG9yaXVtCmBgYHtyIHRob30KdGhvIDwtIHJhc3Rlcih4ID0gImRhdGEvZ3JpZHMvRW52X2NvdmFyaWF0ZXNfbm9DbGltYXRlX1ZpY0dyaWQ5NC9zZXB0MjAxNHRob3JpdW0iKSAlPiUKICBwcm9qZWN0UmFzdGVyKHRvID0gY2hfbWFzaykgJT4lCiAgbWFzayhtYXNrID0gY2hfbWFzaywgZmlsZW5hbWUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9hcmlfdGhvLmdyZCIpICVUPiUKICBwbG90CmBgYAoKIyMjIFZpc2libGUgc2t5IGluZGV4CmBgYHtyIHZza3l9CnZza3kgPC0gcmFzdGVyKHggPSAiZGF0YS9ncmlkcy9FbnZfY292YXJpYXRlc19ub0NsaW1hdGVfVmljR3JpZDk0L3Zpc2libGVfc2t5X3NlcHQyMDEyIikgJT4lCiAgcHJvamVjdFJhc3Rlcih0byA9IGNoX21hc2spICU+JQogIG1hc2sobWFzayA9IGNoX21hc2ssIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvYXJpX3Zza3kuZ3JkIikgJVQ+JQogIHBsb3QKYGBgCgojIyMgVG9wb2dyYXBoaWMgd2V0bmVzcyBpbmRleApgYGB7ciB0d2l9CnR3aSA8LSByYXN0ZXIoeCA9ICJkYXRhL2dyaWRzL0Vudl9jb3ZhcmlhdGVzX25vQ2xpbWF0ZV9WaWNHcmlkOTQvd2V0bmVzc19pbmRleF90b3BvY3JvcF9zZXB0MjAxMiIpICU+JQogIHByb2plY3RSYXN0ZXIodG8gPSBjaF9tYXNrKSAlPiUKICBtYXNrKG1hc2sgPSBjaF9tYXNrLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL2FyaV90d2kuZ3JkIikgJVQ+JQogIHBsb3QKYGBgCgojIyMgV2luZCBleHBvc2l0aW9uCioqUHJvYmxlbSB3aXRoIGxheWVyKioKYGBge3Igd2luZXh9CiMgd2luZXggPC0gcmFzdGVyKHggPSAiZGF0YS9ncmlkcy9FbnZfY292YXJpYXRlc19ub0NsaW1hdGVfVmljR3JpZDk0L3dpbmRfZXhwb3NpdGlvbjIwMTUiKSAlPiUKICAjIHByb2plY3RSYXN0ZXIodG8gPSBjaF9tYXNrKSAlPiUKICAjIG1hc2sobWFzayA9IGNoX21hc2ssIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvYXJpX3dpbmV4LmdyZCIpICVUPiUKICAjIHBsb3QKYGBgCgojIyMgQVJJIHZhcmlhYmxlcyBzdGFjawoKIyMjIyBJbml0aWFsIHZhcmlhYmxlcwpgYGB7ciBhcmlfaXZ9CmFyaV9pdiA8LSBzdGFjayhsdmRhdywgbHZkbWEsIGx2ZG1pLCBsdmRzdykKCm5hbWVzKGFyaV9pdikgPC0gYygibHZkYXciLCAibHZkbWEiLCAibHZkbWkiLCAibHZkc3ciKQpgYGAKCiMjIyMgRnV0dXJlIHZhcmlhYmxlcyAKUmVwZWF0ZXMgaW50byBsaXN0IGZvciBlYWNoIHllYXIKYGBge3IgYXJpX3Z9CmFyaV92IDwtIHZlY3RvcigibGlzdCIsIG50aW1lc3RlcHMgKyAxKQoKZm9yKGkgaW4gMToobnRpbWVzdGVwcysxKSl7CiAgYXJpX3ZbW2ldXSA8LSBhcmlfaXYKfQpgYGAKCgoKIyMgQ2xpbWFjdGljIGRhdGEKcGMgfiBwZXJjZW50YWdlIGNoYW5nZQphYyB+IGFic29sdXRlIGNoYW5nZQoKdG1heCB+IG1heCB0ZW1wZXJhdHVyZQp0bWluIH4gbWluaW11bSB0ZW1wZXJhdHVyZQpwcmVjIH4gcHJlY2lwaXRhdGlvbgpldnRyIH4gZXZhcG90cmFuc3BpcmF0aW9uCgowMSB+IEphbnVhcnkKMDcgfiBKdWx5Cgo0LjUgfiByY3AgNC41CjguNSB+IHJjcCA4LjUKCgojIyMgQ3VycmVudCBjbGltYXRlCkZyb20gV29ybGRDbGltCgojIyMjIFByZWNpcGl0YXRpb24gaW4gSmFudWFyeQpgYGB7ciBwcmVjMDF9CnByZWMwMSA8LSByYXN0ZXIoImRhdGEvZ3JpZHMvd2MyLjBfMzBzX3ByZWNfMDEudGlmIikgJT4lCiAgcHJvamVjdFJhc3Rlcih0byA9IGNoX21hc2spICU+JQogIG1hc2sobWFzayA9IGNoX21hc2ssIGZpbGVuYW1lID0gIm91dHB1dC9jbGltX3ZhcnMvcHJlYzAxLmdyZCIpCgpuYW1lcyhwcmVjMDEpIDwtICJwcmVjMDEiCgpwbG90KHByZWMwMSkKYGBgCgojIyMjIFByZWNpcGl0YXRpb24gaW4gSnVseQpgYGB7ciBwcmVjMDd9CnByZWMwNyA8LSByYXN0ZXIoImRhdGEvZ3JpZHMvd2MyLjBfMzBzX3ByZWNfMDcudGlmIikgJT4lCiAgcHJvamVjdFJhc3Rlcih0byA9IGNoX21hc2spICU+JQogIG1hc2sobWFzayA9IGNoX21hc2ssIGZpbGVuYW1lID0gIm91dHB1dC9jbGltX3ZhcnMvcHJlYzA3LmdyZCIpCgpuYW1lcyhwcmVjMDcpIDwtICJwcmVjMDciCgpwbG90KHByZWMwNykKYGBgCgojIyMjIE1heCB0ZW1wZXJhdHVyZSBpbiBKYW51YXJ5CmBgYHtyIHRtYXgwMX0KdG1heDAxIDwtIHJhc3RlcigiZGF0YS9ncmlkcy93YzIuMF8zMHNfdG1heF8wMS50aWYiKSAlPiUKICBwcm9qZWN0UmFzdGVyKHRvID0gY2hfbWFzaykgJT4lCiAgbWFzayhtYXNrID0gY2hfbWFzaywgZmlsZW5hbWUgPSAib3V0cHV0L2NsaW1fdmFycy90bWF4MDEuZ3JkIikKCm5hbWVzKHRtYXgwMSkgPC0gInRtYXgwMSIKCnBsb3QodG1heDAxKQpgYGAKCiMjIyMgTWluaW11bSB0ZW1wZXJhdHVyZSBpbiBKdWx5CmBgYHtyIHRtaW4wN30KdG1pbjA3IDwtIHJhc3RlcigiZGF0YS9ncmlkcy93YzIuMF8zMHNfdG1pbl8wNy50aWYiKSAlPiUKICBwcm9qZWN0UmFzdGVyKHRvID0gY2hfbWFzaykgJT4lCiAgbWFzayhtYXNrID0gY2hfbWFzaywgZmlsZW5hbWUgPSAib3V0cHV0L2NsaW1fdmFycy90bWluMDcuZ3JkIikKCm5hbWVzKHRtaW4wNykgPC0gInRtaW4wNyIKCnBsb3QodG1pbjA3KQpgYGAKCgojIyMgRnV0dXJlIGNsaW1hdGUKRGF0YSBmcm9tIFtDbGltYXRlIENoYW5nZSBpbiBBdXN0cmFsaWFdKGh0dHBzOi8vd3d3LmNsaW1hdGVjaGFuZ2VpbmF1c3RyYWxpYS5nb3YuYXUvZW4vKQoKIyMjIyBDaGFuZ2UgZGF0YQoqKkNWIGhhcyB1cGRhdGVkKioKIyMjIyMgQWJzb2x1dGUgY2hhbmdlIGluIHRlbXBlcmF0dXJlCmBgYHtyIHJhdyB0ZW1wIGFjfQojYWJzb2x1dGUgY2hhbmdlIGluIHRlbXAKcmF3X3RtYXgwMV80LjVfYWMgPC0gcmVhZC5tdWx0aS5saW5lLmhlYWRlcihmaWxlID0gImh0dHA6Ly9ucm0tZXJkZGFwLm5jaS5vcmcuYXUvZXJkZGFwL2dyaWRkYXAvdGFzbWF4X0Ftb25fQ1NJUk8tTWszLTYtMF9yY3A0NV9yMWkxcDFfYWJzLWNoYW5nZS13cnQtc2Vhc2F2Zy1jbGltX25hdGl2ZS5jc3Y/dGFzbWF4X2phbnVhcnlbKDIwMjUtMDEtMDFUMTI6MDA6MDBaKToxOigyMDkwLTAxLTAxVDEyOjAwOjAwWildWygtNDAuMTAyOTc3NzUpOjE6KC0zMi42NDE5OTQ0OCldWygxNDAuNjI1KToxOigxNTApXSIpCgpyYXdfdG1heDAxXzguNV9hYyA8LSByZWFkLm11bHRpLmxpbmUuaGVhZGVyKGZpbGUgPSAiaHR0cDovL25ybS1lcmRkYXAubmNpLm9yZy5hdS9lcmRkYXAvZ3JpZGRhcC90YXNtYXhfQW1vbl9DU0lSTy1NazMtNi0wX3JjcDg1X3IxaTFwMV9hYnMtY2hhbmdlLXdydC1zZWFzYXZnLWNsaW1fbmF0aXZlLmNzdj90YXNtYXhfamFudWFyeVsoMjAyNS0wMS0wMVQxMjowMDowMFopOjE6KDIwOTAtMDEtMDFUMTI6MDA6MDBaKV1bKC00MC4xMDI5Nzc3NSk6MTooLTMyLjY0MTk5NDQ4KV1bKDE0MC42MjUpOjE6KDE1MCldIikKCnJhd190bWluMDdfNC41X2FjIDwtIHJlYWQubXVsdGkubGluZS5oZWFkZXIoZmlsZSA9ICJodHRwOi8vbnJtLWVyZGRhcC5uY2kub3JnLmF1L2VyZGRhcC9ncmlkZGFwL3Rhc21pbl9BbW9uX0NTSVJPLU1rMy02LTBfcmNwNDVfcjFpMXAxX2Ficy1jaGFuZ2Utd3J0LXNlYXNhdmctY2xpbV9uYXRpdmUuY3N2P3Rhc21pbl9qdWx5WygyMDI1LTAxLTAxVDEyOjAwOjAwWik6MTooMjA5MC0wMS0wMVQxMjowMDowMFopXVsoLTQwLjEwMjk3Nzc1KToxOigtMzIuNjQxOTk0NDgpXVsoMTQwLjYyNSk6MTooMTUwKV0iKSAKCnJhd190bWluMDdfOC41X2FjIDwtIHJlYWQubXVsdGkubGluZS5oZWFkZXIoZmlsZSA9ICJodHRwOi8vbnJtLWVyZGRhcC5uY2kub3JnLmF1L2VyZGRhcC9ncmlkZGFwL3Rhc21pbl9BbW9uX0NTSVJPLU1rMy02LTBfcmNwODVfcjFpMXAxX2Ficy1jaGFuZ2Utd3J0LXNlYXNhdmctY2xpbV9uYXRpdmUuY3N2P3Rhc21pbl9qdWx5WygyMDI1LTAxLTAxVDEyOjAwOjAwWik6MTooMjA5MC0wMS0wMVQxMjowMDowMFopXVsoLTQwLjEwMjk3Nzc1KToxOigtMzIuNjQxOTk0NDgpXVsoMTQwLjYyNSk6MTooMTUwKV0iKQpgYGAKWWVhcnMgZGF0YQpgYGB7ciBuIHRlbXAgYWN9Cm5fdG1heDAxXzQuNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfdG1heDAxXzQuNV9hYyR0aW1lKSkpCm5fdG1heDAxXzguNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfdG1heDAxXzguNV9hYyR0aW1lKSkpCm5fdG1pbjA3XzQuNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfdG1pbjA3XzQuNV9hYyR0aW1lKSkpCm5fdG1pbjA3XzguNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfdG1pbjA3XzguNV9hYyR0aW1lKSkpCmBgYAoKCmBgYHtyIHRtYXggYWN9CnRtYXgwMV80LjVfYWMgPC0gcmFzY2MocmF3X3RtYXgwMV80LjVfYWMsIG5ldy5wcm9qLmxheWVyID0gY2hfbWFzaykKdG1heDAxXzguNV9hYyA8LSByYXNjYyhyYXdfdG1heDAxXzguNV9hYywgbmV3LnByb2oubGF5ZXIgPSBjaF9tYXNrKQp0bWluMDdfNC41X2FjIDwtIHJhc2NjKHJhd190bWluMDdfNC41X2FjLCBuZXcucHJvai5sYXllciA9IGNoX21hc2spCnRtaW4wN184LjVfYWMgPC0gcmFzY2MocmF3X3RtaW4wN184LjVfYWMsIG5ldy5wcm9qLmxheWVyID0gY2hfbWFzaykKYGBgCgoKIyMjIFBlcmNlbnRhZ2UgY2hhbmdlIGluIHByZWNpcGl0YXRpb24KYGBge3J9CnJhd19wcmVjMDFfNC41X3BjIDwtIHJlYWQubXVsdGkubGluZS5oZWFkZXIoZmlsZSA9ICJodHRwOi8vbnJtLWVyZGRhcC5uY2kub3JnLmF1L2VyZGRhcC9ncmlkZGFwL3ByX0Ftb25fQ1NJUk8tTWszLTYtMF9yY3A0NV9yMWkxcDFfcGVyYy1jaGFuZ2Utd3J0LXNlYXNzdW0tY2xpbV9uYXRpdmUuY3N2P3ByX2phbnVhcnlbKDIwMjUtMDEtMDFUMTI6MDA6MDBaKToxOigyMDkwLTAxLTAxVDEyOjAwOjAwWildWygtNDAuMTAyOTc3NzUpOjE6KC0zMi42NDE5OTQ0OCldWygxNDAuNjI1KToxOigxNTApXSIpCgpyYXdfcHJlYzAxXzguNV9wYyA8LSByZWFkLm11bHRpLmxpbmUuaGVhZGVyKGZpbGUgPSAiaHR0cDovL25ybS1lcmRkYXAubmNpLm9yZy5hdS9lcmRkYXAvZ3JpZGRhcC9wcl9BbW9uX0NTSVJPLU1rMy02LTBfcmNwODVfcjFpMXAxX3BlcmMtY2hhbmdlLXdydC1zZWFzc3VtLWNsaW1fbmF0aXZlLmNzdj9wcl9qYW51YXJ5WygyMDI1LTAxLTAxVDEyOjAwOjAwWik6MTooMjA5MC0wMS0wMVQxMjowMDowMFopXVsoLTQwLjEwMjk3Nzc1KToxOigtMzIuNjQxOTk0NDgpXVsoMTQwLjYyNSk6MTooMTUwKV0iKQoKcmF3X3ByZWMwN180LjVfcGMgPC0gcmVhZC5tdWx0aS5saW5lLmhlYWRlcihmaWxlID0gImh0dHA6Ly9ucm0tZXJkZGFwLm5jaS5vcmcuYXUvZXJkZGFwL2dyaWRkYXAvcHJfQW1vbl9DU0lSTy1NazMtNi0wX3JjcDQ1X3IxaTFwMV9wZXJjLWNoYW5nZS13cnQtc2Vhc3N1bS1jbGltX25hdGl2ZS5jc3Y/cHJfanVseVsoMjAyNS0wMS0wMVQxMjowMDowMFopOjE6KDIwOTAtMDEtMDFUMTI6MDA6MDBaKV1bKC00MC4xMDI5Nzc3NSk6MTooLTMyLjY0MTk5NDQ4KV1bKDE0MC42MjUpOjE6KDE1MCldIikKCnJhd19wcmVjMDdfOC41X3BjIDwtIHJlYWQubXVsdGkubGluZS5oZWFkZXIoZmlsZSA9ICJodHRwOi8vbnJtLWVyZGRhcC5uY2kub3JnLmF1L2VyZGRhcC9ncmlkZGFwL3ByX0Ftb25fQ1NJUk8tTWszLTYtMF9yY3A4NV9yMWkxcDFfcGVyYy1jaGFuZ2Utd3J0LXNlYXNzdW0tY2xpbV9uYXRpdmUuY3N2P3ByX2p1bHlbKDIwMjUtMDEtMDFUMTI6MDA6MDBaKToxOigyMDkwLTAxLTAxVDEyOjAwOjAwWildWygtNDAuMTAyOTc3NzUpOjE6KC0zMi42NDE5OTQ0OCldWygxNDAuNjI1KToxOigxNTApXSIpCmBgYAoKYGBge3J9CnByZWMwMV80LjVfcGMgPC0gcmFzY2MocmF3X3ByZWMwMV80LjVfcGMsIG5ldy5wcm9qLmxheWVyID0gY2hfbWFzaykKcHJlYzAxXzguNV9wYyA8LSByYXNjYyhyYXdfcHJlYzAxXzguNV9wYywgbmV3LnByb2oubGF5ZXIgPSBjaF9tYXNrKQpwcmVjMDdfNC41X3BjIDwtIHJhc2NjKHJhd19wcmVjMDdfNC41X3BjLCBuZXcucHJvai5sYXllciA9IGNoX21hc2spCnByZWMwN184LjVfcGMgPC0gcmFzY2MocmF3X3ByZWMwN184LjVfcGMsIG5ldy5wcm9qLmxheWVyID0gY2hfbWFzaykKYGBgCgpgYGB7ciBuX2Jpb2NsaW19Cm5fcHJlYzAxXzQuNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfcHJlYzAxXzQuNV9wYyR0aW1lKSkpCm5fcHJlYzAxXzguNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfcHJlYzAxXzQuNV9wYyR0aW1lKSkpCm5fcHJlYzA3XzQuNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfcHJlYzA3XzQuNV9wYyR0aW1lKSkpCm5fcHJlYzA3XzguNSA8LSBhcy5udW1lcmljKHN1YigiLS4qIiwgIiIsIHVuaXF1ZShyYXdfcHJlYzA3XzQuNV9wYyR0aW1lKSkpCmBgYAoKCiMjIyAgQWJzb2x1dGUgcHJlZGljdGVkIHZhbHVlcwoKIyMjIyBUZW1wZXJhdHVyZQoKYWRkIG5ldyBmdW5jdGlvbiB0aGF0IHdyaXRlcyB0aGVzZSBjbGltYXRlIGxheWVycyB0byBmaWxlcy4KCgojIyMjIyBKYW4gbWF4IHRlbXBlcmF0dXJlIFJDUCA0LjUKYGBge3IgdG1heDAxXzQuNX0KdG1heDAxXzQuNSA8LSB0bWF4MDFfNC41X2FjICsgdG1heDAxCm5hbWVzKHRtYXgwMV80LjUpIDwtIG5hbWVzKHRtYXgwMV80LjVfYWMpCnBsb3QodG1heDAxXzQuNSkKYGBgCgojIyMjIyBKYW4gbWF4IHRlbXBlcmF0dXJlIFJDUCA4LjUKYGBge3IgdG1heDAxXzguNX0KdG1heDAxXzguNSA8LSB0bWF4MDFfOC41X2FjICsgdG1heDAxCm5hbWVzKHRtYXgwMV84LjUpIDwtIG5hbWVzKHRtYXgwMV84LjVfYWMpCnBsb3QodG1heDAxXzguNSkKYGBgCiMjIyMjIEp1bHkgbWluIHRlbXBlcmF0dXJlIFJDUCA0LjUKYGBge3IgdG1pbjA3XzQuNX0KdG1pbjA3XzQuNSA8LSB0bWluMDdfNC41X2FjICsgdG1heDAxCm5hbWVzKHRtaW4wN180LjUpIDwtIG5hbWVzKHRtaW4wN180LjVfYWMpCnBsb3QodG1pbjA3XzQuNSkKYGBgCgojIyMjIyBKdWx5IG1pbiB0ZW1wZXJhdHVyZSBSQ1AgOC41CmBgYHtyfQp0bWluMDdfOC41IDwtIHRtaW4wN184LjVfYWMgKyB0bWF4MDEKbmFtZXModG1pbjA3XzguNSkgPC0gbmFtZXModG1pbjA3XzguNV9hYykKcGxvdCh0bWluMDdfOC41KQpgYGAKCiMjIyMgUHJlY2lwaXRhdGlvbgoKIyMjIyBKYW51YXJ5IHByZWNpcGl0YXRpb24gUkNQIDQuNQpgYGB7cn0KcHJlYzAxXzQuNSA8LSBwcmVjMDEgKiAoMSArIHByZWMwMV80LjVfcGMvMTAwKQpuYW1lcyhwcmVjMDFfNC41KSA8LSBuYW1lcyhwcmVjMDFfNC41X3BjKQpwbG90KHByZWMwMV80LjUpCmBgYAoKIyMjIyBKYW51YXJ5IHByZWNpcGl0YXRpb24gUkNQIDguNQpgYGB7cn0KcHJlYzAxXzguNSA8LSBwcmVjMDEgKiAoMSArIHByZWMwMV84LjVfcGMvMTAwKQpuYW1lcyhwcmVjMDFfOC41KSA8LSBuYW1lcyhwcmVjMDFfOC41X3BjKQpwbG90KHByZWMwMV84LjUpCmBgYAoKIyMjIyBKdWx5IHByZWNpcGl0YXRpb24gUkNQIDQuNQpgYGB7cn0KcHJlYzA3XzQuNSA8LSBwcmVjMDcgKiAoMSArIHByZWMwN180LjVfcGMvMTAwKQpuYW1lcyhwcmVjMDdfNC41KSA8LSBuYW1lcyhwcmVjMDdfNC41X3BjKQpwbG90KHByZWMwN180LjUpCmBgYAoKIyMjIyBKdWx5IHByZWNpcGl0YXRpb24gUkNQIDguNQpgYGB7cn0KcHJlYzA3XzguNSA8LSBwcmVjMDcgKiAoMSArIHByZWMwN184LjVfcGMvMTAwKQpuYW1lcyhwcmVjMDdfOC41KSA8LSBuYW1lcyhwcmVjMDdfOC41X3BjKQpwbG90KHByZWMwN184LjUpCmBgYAoKIyMjIEludGVycGxvYXRlIHByZWRpY3Rpb24gZGF0YQoqKkN1cnJlbnRseSBqdXN0IHJlcGVhdHMgcHJlZGljdGlvbnMsIG5lZWQgdXBkYXRpbmcgdG8gd2VpZ2h0IHByZWRpY3Rpb25zIHdpdGhpbiAxMCB5ZWFycywgY2YgZGF0YSBmcm9tIENTSVJPKioKCmBgYHtyfQp0bWF4MDFfNC41X2ludCA8LSBpbnRlcnBvbGF0ZS5jbGltZGF0KHRtYXgwMSwgdG1heDAxXzQuNSwgbnkgPSA1MCwgbmYgPSBuX3RtYXgwMV80LjUsIG4wID0gMjAxOSwgdmFybmFtZSA9ICJ0bWF4MDEiKQp0bWF4MDFfOC41X2ludCA8LSBpbnRlcnBvbGF0ZS5jbGltZGF0KHRtYXgwMSwgdG1heDAxXzguNSwgbnkgPSA1MCwgbmYgPSBuX3RtYXgwMV84LjUsIG4wID0gMjAxOSwgdmFybmFtZSA9ICJ0bWF4MDEiKQp0bWluMDdfNC41X2ludCA8LSBpbnRlcnBvbGF0ZS5jbGltZGF0KHRtaW4wNywgdG1pbjA3XzQuNSwgbnkgPSA1MCwgbmYgPSBuX3RtaW4wN180LjUsIG4wID0gMjAxOSwgdmFybmFtZSA9ICJ0bWluMDciKQp0bWluMDdfOC41X2ludCA8LSBpbnRlcnBvbGF0ZS5jbGltZGF0KHRtaW4wNywgdG1pbjA3XzguNSwgbnkgPSA1MCwgbmYgPSBuX3RtaW4wN184LjUsIG4wID0gMjAxOSwgdmFybmFtZSA9ICJ0bWluMDciKQoKcHJlYzAxXzQuNV9pbnQgPC0gaW50ZXJwb2xhdGUuY2xpbWRhdChwcmVjMDEsIHByZWMwMV80LjUsIG55ID0gNTAsIG5mID0gbl9wcmVjMDFfNC41LCBuMCA9IDIwMTksIHZhcm5hbWUgPSAicHJlYzAxIikKcHJlYzAxXzguNV9pbnQgPC0gaW50ZXJwb2xhdGUuY2xpbWRhdChwcmVjMDEsIHByZWMwMV84LjUsIG55ID0gNTAsIG5mID0gbl9wcmVjMDFfOC41LCBuMCA9IDIwMTksIHZhcm5hbWUgPSAicHJlYzAxIikKcHJlYzA3XzQuNV9pbnQgPC0gaW50ZXJwb2xhdGUuY2xpbWRhdChwcmVjMDcsIHByZWMwN180LjUsIG55ID0gNTAsIG5mID0gbl9wcmVjMDdfNC41LCBuMCA9IDIwMTksIHZhcm5hbWUgPSAicHJlYzA3IikKcHJlYzA3XzguNV9pbnQgPC0gaW50ZXJwb2xhdGUuY2xpbWRhdChwcmVjMDcsIHByZWMwN184LjUsIG55ID0gNTAsIG5mID0gbl9wcmVjMDdfOC41LCBuMCA9IDIwMTksIHZhcm5hbWUgPSAicHJlYzA3IikKYGBgCgojIyMgQ2xpbWF0ZSB2YXJpYWJsZSBzZXRzCgojIyMjIEluaXRpYWwgY2xpbWF0ZSB2YXJpYWJsZXMKYGBge3IgY2xpbSBpdn0KY2xpbV9pdiA8LSBzdGFjayhwcmVjMDEsIHByZWMwNywgdG1heDAxLCB0bWluMDcpCmBgYAoKIyMjIyBGdXR1cmUgY2xpbWF0ZSB2YXJpYWJsZXMKYGBge3IgY2xpbV9mdn0KY2xpbV9mdl9jYzAgPC0gdmVjdG9yKCJsaXN0IiwgNTApCmZvcihpIGluIDE6NTApewogIGNsaW1fZnZfY2MwW1tpXV0gPC0gY2xpbV9pdgp9CgoKY2xpbV9mdl80LjUgPC0gbWFwcGx5KHByZWMwMV80LjVfaW50LCBwcmVjMDdfNC41X2ludCwgdG1heDAxXzQuNV9pbnQsIHRtaW4wN180LjVfaW50LCBGVU4gPSBzdGFjaykKY2xpbV9mdl84LjUgPC0gbWFwcGx5KHByZWMwMV84LjVfaW50LCBwcmVjMDdfOC41X2ludCwgdG1heDAxXzguNV9pbnQsIHRtaW4wN184LjVfaW50LCBGVU4gPSBzdGFjaykKYGBgCgpgYGB7cn0Kc2F2ZS5pbWFnZShmaWxlID0gIm91dHB1dC9pbnB1dF92YXJpYWJsZXMuUkRhdGEiKQpgYGAKCgojIyBEaXN0cmlidXRpb24gbW9kZWwgdmFyaWFibGVzCgojIyMgU3BlY2llcyBMQU5ESVMgdmFyaWFibGVzCgojIyMjIEdHIExBTkRJUyB2YXJzCmBgYHtyIGdnX2x2fQpnZ2x2IDwtIGMoImdnZiIsICJnZ2QiLCAiaGJ0XzFrIikKYGBgCgoKIyMjIyBMQiBMQU5ESVMgdmFycwpgYGB7cn0KbGJsdiA8LSBjKCJsYm0iLCAiaGJ0XzNoIikKYGBgCgoKIyMjIFNjZW5hcmlvIDEKCiMjIyMgR3JlYXRlciBHbGlkZXIKCiMjIyMjIFNjZW5hcmlvIDEgaW5pdGlhbCB2YXJpYWJsZXMKYGBge3IgczFfaXZfZ2d9CnMxX2l2X2dnIDwtIHN0YWNrKHMxX3ZhcnNfbGFuZGlzX2luaXRbW2MoZ2dsdildXSwgY2xpbV9pdikKCnNhdmUoczFfaXZfZ2csIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zMV9pdl9nZyIpCmBgYAoKIyMjIyMgU2NlbmFpbyAxIG1vZGVsIGRhdGEKYGBge3J9CnMxX21kX2dnIDwtIHMxX2l2X2dnICU+JQogIHJhc3Rlcjo6ZXh0cmFjdCh5ID0gc3RfY29vcmRpbmF0ZXMoZ2dfcGFfY2gpKSAlPiUKICBjYmluZCgiUEEiID0gZ2dfcGFfY2gkUEEsIC4pICU+JQogIGFzLmRhdGEuZnJhbWUgJT4lCiAgbmEub21pdCAKCnMxX21kX2dnCgpzYXZlKHMxX21kX2dnLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczFfbWRfZ2ciKQpgYGAKCgojIyMjIyBTY2VuYXJpbyAxIGZ1dHVyZSB2YXJpYWJsZXMKYGBge3IgczFfZnZfZ2d9CnMxX2Z2X2dnIDwtIHMxX3ZhcnNfbGFuZGlzX2Z1dCAlPiUKICBzYXBwbHkoIltbIiwgZ2dsdikgJT4lCiAgbWFwcGx5KGNsaW1fZnZfNC41LCBGVU4gPSBzdGFjaykKCnNhdmUoczFfZnZfZ2csIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zMV9mdl9nZyIpCmBgYAoKCiMjIyMgTGVhZGJlYXRlcidzIFBvc3N1bQoKIyMjIyMgU2NlbmFyaW8gMSBpbml0aWFsIHZhcmlhYmxlcwpgYGB7ciBzMV9pdl9sYn0KczFfaXZfbGIgPC0gc3RhY2soczFfdmFyc19sYW5kaXNfaW5pdFtbYyhsYmx2KV1dLCBjbGltX2l2KQoKc2F2ZShzMV9pdl9sYiwgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3MxX2l2X2xiIikKYGBgCgojIyMjIyBTY2VuYWlvIDEgbW9kZWwgZGF0YQpgYGB7cn0KczFfbWRfbGIgPC0gczFfaXZfbGIgJT4lCiAgcmFzdGVyOjpleHRyYWN0KHkgPSBzdF9jb29yZGluYXRlcyhsYl9wYV9jaCkpICU+JQogIGNiaW5kKCJQQSIgPSBsYl9wYV9jaCRQQSwgLikgJT4lCiAgYXMuZGF0YS5mcmFtZSAlPiUKICBuYS5vbWl0IAoKczFfbWRfbGIKCnNhdmUoczFfbWRfbGIsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zMV9tZF9sYiIpCmBgYAoKCiMjIyMjIFNjZW5hcmlvIDEgZnV0dXJlIHZhcmlhYmxlcwpgYGB7ciBzMV9mdl9sYn0KczFfZnZfbGIgPC0gczFfdmFyc19sYW5kaXNfZnV0ICU+JQogIHNhcHBseSgiW1siLCBsYmx2KSAlPiUKICBtYXBwbHkoY2xpbV9mdl80LjUsIEZVTiA9IHN0YWNrKQoKc2F2ZShzMV9mdl9sYiwgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3MxX2Z2X2xiIikKYGBgCgojIyMgU2NlbmFyaW8gMgoqKmF3YWl0aW5nIHVwZGF0ZWQgY2xpbWF0ZSB2YXJpYWJsZXMqKgoKCiMjIyBTY2VuYXJpbyAzCgojIyMjIEdyZWF0ZXIgR2xpZGVyCgojIyMjIyBTY2VuYXJpbyAzIGluaXRpYWwgdmFyaWFibGVzCmBgYHtyIHMzX2l2X2dnfQpzM19pdl9nZyA8LSBzdGFjayhzM192YXJzX2xhbmRpc19pbml0W1tjKGdnbHYpXV0sIGNsaW1faXYpCgpzYXZlKHMzX2l2X2dnLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczNfaXZfZ2ciKQpgYGAKCiMjIyMjIFNjZW5haW8gMyBtb2RlbCBkYXRhCmBgYHtyfQpzM19tZF9nZyA8LSBzM19pdl9nZyAlPiUKICByYXN0ZXI6OmV4dHJhY3QoeSA9IHN0X2Nvb3JkaW5hdGVzKGdnX3BhX2NoKSkgJT4lCiAgY2JpbmQoIlBBIiA9IGdnX3BhX2NoJFBBLCAuKSAlPiUKICBhcy5kYXRhLmZyYW1lICU+JQogIG5hLm9taXQgCgpzM19tZF9nZwoKc2F2ZShzM19tZF9nZywgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3MzX21kX2dnIikKYGBgCgoKIyMjIyMgU2NlbmFyaW8gMyBmdXR1cmUgdmFyaWFibGVzCmBgYHtyIHMzX2Z2X2dnfQpzM19mdl9nZyA8LSBzM192YXJzX2xhbmRpc19mdXQgJT4lCiAgc2FwcGx5KCJbWyIsIGdnbHYpICU+JQogIG1hcHBseShjbGltX2Z2X2NjMCwgRlVOID0gc3RhY2spCgpzYXZlKHMzX2Z2X2dnLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczNfZnZfZ2ciKQpgYGAKCgojIyMjIExlYWRiZWF0ZXIncyBQb3NzdW0KCiMjIyMjIFNjZW5hcmlvIDMgaW5pdGlhbCB2YXJpYWJsZXMKYGBge3IgczNfaXZfbGJ9CnMzX2l2X2xiIDwtIHN0YWNrKHMzX3ZhcnNfbGFuZGlzX2luaXRbW2MobGJsdildXSwgY2xpbV9pdikKCnNhdmUoczNfaXZfbGIsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zM19pdl9sYiIpCmBgYAoKIyMjIyMgU2NlbmFpbyAzIG1vZGVsIGRhdGEKYGBge3J9CnMzX21kX2xiIDwtIHMzX2l2X2xiICU+JQogIHJhc3Rlcjo6ZXh0cmFjdCh5ID0gc3RfY29vcmRpbmF0ZXMobGJfcGFfY2gpKSAlPiUKICBjYmluZCgiUEEiID0gbGJfcGFfY2gkUEEsIC4pICU+JQogIGFzLmRhdGEuZnJhbWUgJT4lCiAgbmEub21pdCAKCnMzX21kX2xiCgpzYXZlKHMzX21kX2xiLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczNfbWRfbGIiKQpgYGAKCgojIyMjIyBTY2VuYXJpbyAzIGZ1dHVyZSB2YXJpYWJsZXMKYGBge3IgczNfZnZfbGJ9CnMzX2Z2X2xiIDwtIHMzX3ZhcnNfbGFuZGlzX2Z1dCAlPiUKICBzYXBwbHkoIltbIiwgbGJsdikgJT4lCiAgbWFwcGx5KGNsaW1fZnZfY2MwLCBGVU4gPSBzdGFjaykKCnNhdmUoczNfZnZfbGIsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zM19mdl9sYiIpCmBgYAoKCiMjIyBTY2VuYXJpbyA0CgojIyMjIEdyZWF0ZXIgR2xpZGVyCgojIyMjIyBTY2VuYXJpbyA0IGluaXRpYWwgdmFyaWFibGVzCmBgYHtyIHM0X2l2X2dnfQpzNF9pdl9nZyA8LSBzdGFjayhzNF92YXJzX2xhbmRpc19pbml0W1tjKGdnbHYpXV0sIGNsaW1faXYpCgpzYXZlKHM0X2l2X2dnLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczRfaXZfZ2ciKQpgYGAKCiMjIyMjIFNjZW5haW8gNCBtb2RlbCBkYXRhCmBgYHtyfQpzNF9tZF9nZyA8LSBzNF9pdl9nZyAlPiUKICByYXN0ZXI6OmV4dHJhY3QoeSA9IHN0X2Nvb3JkaW5hdGVzKGdnX3BhX2NoKSkgJT4lCiAgY2JpbmQoIlBBIiA9IGdnX3BhX2NoJFBBLCAuKSAlPiUKICBhcy5kYXRhLmZyYW1lICU+JQogIG5hLm9taXQgCgpzNF9tZF9nZwoKc2F2ZShzNF9tZF9nZywgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF92YXJzL3M0X21kX2dnIikKYGBgCgoKIyMjIyMgU2NlbmFyaW8gNCBmdXR1cmUgdmFyaWFibGVzCmBgYHtyIHM0X2Z2X2dnfQpzNF9mdl9nZyA8LSBzNF92YXJzX2xhbmRpc19mdXQgJT4lCiAgc2FwcGx5KCJbWyIsIGdnbHYpICU+JQogIG1hcHBseShjbGltX2Z2XzQuNSwgRlVOID0gc3RhY2spCgpzYXZlKHM0X2Z2X2dnLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczRfZnZfZ2ciKQpgYGAKCgojIyMjIExlYWRiZWF0ZXIncyBQb3NzdW0KCiMjIyMjIFNjZW5hcmlvIDQgaW5pdGlhbCB2YXJpYWJsZXMKYGBge3IgczRfaXZfbGJ9CnM0X2l2X2xiIDwtIHN0YWNrKHM0X3ZhcnNfbGFuZGlzX2luaXRbW2MobGJsdildXSwgY2xpbV9pdikKCnNhdmUoczRfaXZfbGIsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zNF9pdl9sYiIpCmBgYAoKIyMjIyMgU2NlbmFpbyA0IG1vZGVsIGRhdGEKYGBge3J9CnM0X21kX2xiIDwtIHM0X2l2X2xiICU+JQogIHJhc3Rlcjo6ZXh0cmFjdCh5ID0gc3RfY29vcmRpbmF0ZXMobGJfcGFfY2gpKSAlPiUKICBjYmluZCgiUEEiID0gbGJfcGFfY2gkUEEsIC4pICU+JQogIGFzLmRhdGEuZnJhbWUgJT4lCiAgbmEub21pdCAKCnM0X21kX2xiCgpzYXZlKHM0X21kX2xiLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ZhcnMvczRfbWRfbGIiKQpgYGAKCgojIyMjIyBTY2VuYXJpbyA0IGZ1dHVyZSB2YXJpYWJsZXMKYGBge3IgczRfZnZfbGJ9CnM0X2Z2X2xiIDwtIHM0X3ZhcnNfbGFuZGlzX2Z1dCAlPiUKICBzYXBwbHkoIltbIiwgbGJsdikgJT4lCiAgbWFwcGx5KGNsaW1fZnZfNC41LCBGVU4gPSBzdGFjaykKCnNhdmUoczRfZnZfbGIsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfdmFycy9zNF9mdl9sYiIpCmBgYAoKCiMgRGlzdHJpYnV0aW9uIG1vZGVsIGZpdCBhbmQgcHJlZGljdGlvbgoKIyMgR3JlYXRlciBHbGlkZXIKCiMjIyBTY2VuYXJpbyAxCmBgYHtyIHMxX21vZF9nZ30KczFfbW9kX2dnIDwtIGdibS5zdGVwKGRhdGEgPSBzMV9tZF9nZywgZ2JtLnggPSAyOjgsIGdibS55ID0gMSwgZmFtaWx5ID0gImJlcm5vdWxsaSIsIHRyZWUuY29tcGxleGl0eSA9IDUsIGxlYXJuaW5nLnJhdGUgPSAwLjAwMSwgc3RlcC5zaXplID0gMSwgYmFnLmZyYWN0aW9uID0gMC41LCBwcmV2LnN0cmF0aWZ5ID0gRkFMU0UsIHZlcmJvc2UgPSBGQUxTRSwgbWF4LnRyZWVzID0gMTAwMCkKYGBgCmBgYHtyIHN1bWFyeSBzMV9tb2RfZ2d9CnN1bW1hcnkoczFfbW9kX2dnKQpgYGAKCmBgYHtyIHMxX2lwX2dnfQojczFfaXBfZ2cgPC0gcHJlZGljdChzMV9pdl9nZywgczFfbW9kX2dnLCB0eXBlID0gInJlc3BvbnNlIiwgbi50cmVlcyA9IHMxX21vZF9nZyRnYm0uY2FsbCRiZXN0LnRyZWVzLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MxX2ZwX2dnLTAwMC50aWYiKQoKI3dyaXRlUmFzdGVyKHMxX2lwX2dnLCAib3V0cHV0L2hhYml0YXRfcHJlZC9zMV9pcF9nZy50aWYiLCBvdmVyd3JpdGUgPSBUUlVFKQpzMV9pcF9nZyA8LSByYXN0ZXIoeCA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MxX2lwX2dnLnRpZiIpCgpwbG90KHMxX2lwX2dnKQpgYGAKCmBgYHtyIHMxX2ZwX2dnfQpyZWdpc3RlckRvTUMoY29yZXMgPSAyMCkKCnMxX2ZwX2dnIDwtIGZvcmVhY2goaSA9IHNlcV9sZW4obGVuZ3RoKHMxX2Z2X2dnKSkpICVkb3BhciUgewogIHByZWRpY3QoczFfZnZfZ2dbW2ldXSwKICAgICAgICAgIHMxX21vZF9nZywKICAgICAgICAgIHR5cGUgPSAicmVzcG9uc2UiLAogICAgICAgICAgbi50cmVlcyA9IHMxX21vZF9nZyRnYm0uY2FsbCRiZXN0LnRyZWVzLAogICAgICAgICAgZmlsZW5hbWUgPSBwYXN0ZTAoIm91dHB1dC9oYWJpdGF0X3ByZWQvczFfZnBfZ2ctIiwgc3ByaW50ZigiJTAzZCIsIGkpLCAiLnRpZiIpLAogICAgICAgICAgb3ZlcndyaXRlID0gVFJVRSkKfQoKczFfZnBfZ2cgPC0gc3RhY2soczFfZnBfZ2cpCmBgYAoKYGBge3Igc2F2ZSBzMV9mcF9nZ30Kc2F2ZShzMV9mcF9nZywgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MxX2ZwX2dnIikKd3JpdGVSYXN0ZXIoczFfZnBfZ2csIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ByZWQvczFfZnBfZ2cudGlmIikKYGBgCgoKIyMjIFNjZW5hcmlvIDMKYGBge3IgczNfbW9kX2dnfQpzM19tb2RfZ2cgPC0gZ2JtLnN0ZXAoZGF0YSA9IHMzX21kX2dnLCBnYm0ueCA9IDM6NywgZ2JtLnkgPSAxLCBmYW1pbHkgPSAiYmVybm91bGxpIiwgdHJlZS5jb21wbGV4aXR5ID0gNSwgbGVhcm5pbmcucmF0ZSA9IDAuMDAxLCBzdGVwLnNpemUgPSAxLCBiYWcuZnJhY3Rpb24gPSAwLjUsIHByZXYuc3RyYXRpZnkgPSBGQUxTRSwgdmVyYm9zZSA9IEZBTFNFLCBtYXgudHJlZXMgPSAxMDAwKQpgYGAKYGBge3Igc3VtYXJ5IHMzX21vZF9nZ30Kc3VtbWFyeShzM19tb2RfZ2cpCmBgYAoKYGBge3IgczNfaXBfZ2d9CiAjIHMzX2lwX2dnIDwtIHByZWRpY3QoczNfaXZfZ2csIHMzX21vZF9nZywgdHlwZSA9ICJyZXNwb25zZSIsIG4udHJlZXMgPSBzM19tb2RfZ2ckZ2JtLmNhbGwkYmVzdC50cmVlcywgZmlsZW5hbWUgPSJvdXRwdXQvaGFiaXRhdF9wcmVkL3MzX2ZwX2dnLTAwMC50aWYiKQoKICMgd3JpdGVSYXN0ZXIoczNfaXBfZ2csICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MzX2lwX2dnLnRpZiIsIG92ZXJ3cml0ZSA9IFRSVUUpCgpzM19pcF9nZyA8LSByYXN0ZXIoeCA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MzX2lwX2dnLnRpZiIpCgpwbG90KHMzX2lwX2dnKQpgYGAKCmBgYHtyIHMzX2ZwX2dnfQpyZWdpc3RlckRvTUMoY29yZXMgPSAyMCkKCnMzX2ZwX2dnIDwtIGZvcmVhY2goaSA9IHNlcV9sZW4obGVuZ3RoKHMzX2Z2X2dnKSkpICVkb3BhciUgewogIHByZWRpY3QoczNfZnZfZ2dbW2ldXSwKICAgICAgICAgIHMzX21vZF9nZywKICAgICAgICAgIHR5cGUgPSAicmVzcG9uc2UiLAogICAgICAgICAgbi50cmVlcyA9IHMzX21vZF9nZyRnYm0uY2FsbCRiZXN0LnRyZWVzLAogICAgICAgICAgZmlsZW5hbWUgPSBwYXN0ZTAoIm91dHB1dC9oYWJpdGF0X3ByZWQvczNfZnBfZ2ctIiwgc3ByaW50ZigiJTAzZCIsIGkpLCAiLnRpZiIpLAogICAgICAgICAgb3ZlcndyaXRlID0gVFJVRSkKfQoKczNfZnBfZ2cgPC0gc3RhY2soczNfZnBfZ2cpCmBgYAoKYGBge3Igc2F2ZSBzM19mcF9nZ30Kc2F2ZShzM19mcF9nZywgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MzX2ZwX2dnIikKd3JpdGVSYXN0ZXIoczNfZnBfZ2csIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ByZWQvczNfZnBfZ2cudGlmIikKYGBgCgojIyMgU2NlbmFyaW8gNApgYGB7ciBzNF9tb2RfZ2d9CnM0X21vZF9nZyA8LSBnYm0uc3RlcChkYXRhID0gczRfbWRfZ2csIGdibS54ID0gMjo4LCBnYm0ueSA9IDEsIGZhbWlseSA9ICJiZXJub3VsbGkiLCB0cmVlLmNvbXBsZXhpdHkgPSA1LCBsZWFybmluZy5yYXRlID0gMC4wMDEsIHN0ZXAuc2l6ZSA9IDEsIGJhZy5mcmFjdGlvbiA9IDAuNSwgcHJldi5zdHJhdGlmeSA9IEZBTFNFLCB2ZXJib3NlID0gRkFMU0UsIG1heC50cmVlcyA9IDEwMDApCmBgYApgYGB7ciBzdW1hcnkgczRfbW9kX2dnfQpzdW1tYXJ5KHM0X21vZF9nZykKYGBgCgpgYGB7ciBzNF9pcF9nZ30KIyBzNF9pcF9nZyA8LSBwcmVkaWN0KHM0X2l2X2dnLCBzNF9tb2RfZ2csIHR5cGUgPSAicmVzcG9uc2UiLCBuLnRyZWVzID0gczRfbW9kX2dnJGdibS5jYWxsJGJlc3QudHJlZXMsICBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkLzRfZnBfZ2ctMDAwLnRpZiIpCgojIHdyaXRlUmFzdGVyKHM0X2lwX2dnLCAib3V0cHV0L2hhYml0YXRfcHJlZC9zNF9pcF9nZy50aWYiLCBvdmVyd3JpdGUgPSBUUlVFKQoKczRfaXBfZ2cgPC0gcmFzdGVyKHggPSAib3V0cHV0L2hhYml0YXRfcHJlZC9zNF9pcF9nZy50aWYiKQoKcGxvdChzNF9pcF9nZykKYGBgCgpgYGB7ciBzNF9mcF9nZ30KcmVnaXN0ZXJEb01DKGNvcmVzID0gMjApCgpzNF9mcF9nZyA8LSBmb3JlYWNoKGkgPSBzZXFfbGVuKGxlbmd0aChzNF9mdl9nZykpKSAlZG9wYXIlIHsKICBwcmVkaWN0KHM0X2Z2X2dnW1tpXV0sCiAgICAgICAgICBzNF9tb2RfZ2csCiAgICAgICAgICB0eXBlID0gInJlc3BvbnNlIiwKICAgICAgICAgIG4udHJlZXMgPSBzNF9tb2RfZ2ckZ2JtLmNhbGwkYmVzdC50cmVlcywKICAgICAgICAgIGZpbGVuYW1lID0gcGFzdGUwKCJvdXRwdXQvaGFiaXRhdF9wcmVkL3M0X2ZwX2dnLSIsIHNwcmludGYoIiUwM2QiLCBpKSwgIi50aWYiKSwKICAgICAgICAgIG92ZXJ3cml0ZSA9IFRSVUUpCn0KCnM0X2ZwX2dnIDwtIHN0YWNrKHM0X2ZwX2dnKQpgYGAKCmBgYHtyIHNhdmUgczRfZnBfZ2d9CnNhdmUoczRfZnBfZ2csIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfcHJlZC9zNF9mcF9nZyIpCndyaXRlUmFzdGVyKHM0X2ZwX2dnLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3M0X2ZwX2dnLnRpZiIpCmBgYAoKCiMjIExlYWRiZWF0ZXIncyBQb3NzdW0KCgojIyMgU2NlbmFyaW8gMQpgYGB7ciBzMV9tb2RfbGJ9CnMxX21vZF9sYiA8LSBnYm0uc3RlcChkYXRhID0gczFfbWRfbGIsIGdibS54ID0gMjo3LCBnYm0ueSA9IDEsIGZhbWlseSA9ICJiZXJub3VsbGkiLCB0cmVlLmNvbXBsZXhpdHkgPSA1LCBsZWFybmluZy5yYXRlID0gMC4wMDEsIHN0ZXAuc2l6ZSA9IDEsIGJhZy5mcmFjdGlvbiA9IDAuNSwgcHJldi5zdHJhdGlmeSA9IEZBTFNFLCB2ZXJib3NlID0gRkFMU0UsIG1heC50cmVlcyA9IDEwMDApCmBgYApgYGB7ciBzdW1hcnkgczFfbW9kX2xifQpzdW1tYXJ5KHMxX21vZF9sYikKYGBgCgpgYGB7ciBzMV9pcF9sYn0KIyBzMV9pcF9sYiA8LSBwcmVkaWN0KHMxX2l2X2xiLCBzMV9tb2RfbGIsIHR5cGUgPSAicmVzcG9uc2UiLCBuLnRyZWVzID0gczFfbW9kX2xiJGdibS5jYWxsJGJlc3QudHJlZXMsIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ByZWQvczFfZnBfbGItMDAwLnRpZiIpCgojIHdyaXRlUmFzdGVyKHMxX2lwX2xiLCAib3V0cHV0L2hhYml0YXRfcHJlZC9zMV9pcF9sYi50aWYiLCBvdmVyd3JpdGUgPSBUUlVFKQoKczFfaXBfbGIgPC0gcmFzdGVyKHggPSAib3V0cHV0L2hhYml0YXRfcHJlZC9zMV9pcF9sYi50aWYiKQoKcGxvdChzMV9pcF9sYikKYGBgCgpgYGB7ciBzMV9mcF9sYn0KcmVnaXN0ZXJEb01DKGNvcmVzID0gMjApCgpzMV9mcF9sYiA8LSBmb3JlYWNoKGkgPSBzZXFfbGVuKGxlbmd0aChzMV9mdl9sYikpKSAlZG9wYXIlIHsKICBwcmVkaWN0KHMxX2Z2X2xiW1tpXV0sCiAgICAgICAgICBzMV9tb2RfbGIsCiAgICAgICAgICB0eXBlID0gInJlc3BvbnNlIiwKICAgICAgICAgIG4udHJlZXMgPSBzMV9tb2RfbGIkZ2JtLmNhbGwkYmVzdC50cmVlcywKICAgICAgICAgIGZpbGVuYW1lID0gcGFzdGUwKCJvdXRwdXQvaGFiaXRhdF9wcmVkL3MxX2ZwX2xiLSIsIHNwcmludGYoIiUwM2QiLCBpKSwgIi50aWYiKSwKICAgICAgICAgIG92ZXJ3cml0ZSA9IFRSVUUpCn0KCnMxX2ZwX2xiIDwtIHN0YWNrKHMxX2ZwX2xiKQpgYGAKCmBgYHtyIHNhdmUgczFfZnBfbGJ9CnNhdmUoczFfZnBfbGIsIGZpbGUgPSAib3V0cHV0L2hhYml0YXRfcHJlZC9zMV9mcF9sYiIpCndyaXRlUmFzdGVyKHMxX2ZwX2xiLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MxX2ZwX2xiLnRpZiIpCmBgYAoKIyMjIFNjZW5hcmlvIDMKYGBge3IgczNfbW9kX2xifQpzM19tb2RfbGIgPC0gZ2JtLnN0ZXAoZGF0YSA9IHMzX21kX2xiLCBnYm0ueCA9IDI6NywgZ2JtLnkgPSAxLCBmYW1pbHkgPSAiYmVybm91bGxpIiwgdHJlZS5jb21wbGV4aXR5ID0gNSwgbGVhcm5pbmcucmF0ZSA9IDAuMDAxLCBzdGVwLnNpemUgPSAxLCBiYWcuZnJhY3Rpb24gPSAwLjUsIHByZXYuc3RyYXRpZnkgPSBGQUxTRSwgdmVyYm9zZSA9IEZBTFNFLCBtYXgudHJlZXMgPSAxMDAwKQpgYGAKYGBge3Igc3VtYXJ5IHMzX21vZF9sYn0Kc3VtbWFyeShzM19tb2RfbGIpCmBgYAoKYGBge3IgczNfaXBfbGJ9CiMgczNfaXBfbGIgPC0gcHJlZGljdChzM19pdl9sYiwgczNfbW9kX2xiLCB0eXBlID0gInJlc3BvbnNlIiwgbi50cmVlcyA9IHMzX21vZF9sYiRnYm0uY2FsbCRiZXN0LnRyZWVzLCBmaWxlbmFtZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3MzX2ZwX2xiLTAwMC50aWYiKQoKIyB3cml0ZVJhc3RlcihzM19pcF9sYiwgIm91dHB1dC9oYWJpdGF0X3ByZWQvczNfaXBfbGIudGlmIiwgb3ZlcndyaXRlID0gVFJVRSkKCnMzX2lwX2xiIDwtIHJhc3Rlcih4ID0gIm91dHB1dC9oYWJpdGF0X3ByZWQvczNfaXBfbGIudGlmIikKCnBsb3QoczNfaXBfbGIpCmBgYAoKYGBge3IgczNfZnBfbGJ9CnJlZ2lzdGVyRG9NQyhjb3JlcyA9IDIwKQoKczNfZnBfbGIgPC0gZm9yZWFjaChpID0gc2VxX2xlbihsZW5ndGgoczNfZnZfbGIpKSkgJWRvcGFyJSB7CiAgcHJlZGljdChzM19mdl9sYltbaV1dLAogICAgICAgICAgczNfbW9kX2xiLAogICAgICAgICAgdHlwZSA9ICJyZXNwb25zZSIsCiAgICAgICAgICBuLnRyZWVzID0gczNfbW9kX2xiJGdibS5jYWxsJGJlc3QudHJlZXMsCiAgICAgICAgICBmaWxlbmFtZSA9IHBhc3RlMCgib3V0cHV0L2hhYml0YXRfcHJlZC9zM19mcF9sYi0iLCBzcHJpbnRmKCIlMDNkIiwgaSksICIudGlmIiksCiAgICAgICAgICBvdmVyd3JpdGUgPSBUUlVFKQp9CgpzM19mcF9sYiA8LSBzdGFjayhzM19mcF9sYikKYGBgCgpgYGB7ciBzYXZlIHMzX2ZwX2xifQpzYXZlKHMzX2ZwX2xiLCBmaWxlID0gIm91dHB1dC9oYWJpdGF0X3ByZWQvczNfZnBfbGIiKQp3cml0ZVJhc3RlcihzM19mcF9sYiwgZmlsZW5hbWUgPSAib3V0cHV0L2hhYml0YXRfcHJlZC9zM19mcF9sYi50aWYiKQpgYGAKCiMjIyBTY2VuYXJpbyA0CmBgYHtyIHM0X21vZF9sYn0KczRfbW9kX2xiIDwtIGdibS5zdGVwKGRhdGEgPSBzNF9tZF9sYiwgZ2JtLnggPSAyOjcsIGdibS55ID0gMSwgZmFtaWx5ID0gImJlcm5vdWxsaSIsIHRyZWUuY29tcGxleGl0eSA9IDUsIGxlYXJuaW5nLnJhdGUgPSAwLjAwMSwgc3RlcC5zaXplID0gMSwgYmFnLmZyYWN0aW9uID0gMC41LCBwcmV2LnN0cmF0aWZ5ID0gRkFMU0UsIHZlcmJvc2UgPSBGQUxTRSwgbWF4LnRyZWVzID0gMTAwMCkKYGBgCmBgYHtyIHN1bWFyeSBzNF9tb2RfbGJ9CnN1bW1hcnkoczRfbW9kX2xiKQpgYGAKCmBgYHtyIHM0X2lwX2xifQojIHM0X2lwX2xiIDwtIHByZWRpY3QoczRfaXZfbGIsIHM0X21vZF9sYiwgdHlwZSA9ICJyZXNwb25zZSIsIG4udHJlZXMgPSBzNF9tb2RfbGIkZ2JtLmNhbGwkYmVzdC50cmVlcywgZmlsZW5hbWUgPSAib3V0cHV0L2hhYml0YXRfcHJlZC9zNF9mcF9sYi0wMDAudGlmIikKCiMgd3JpdGVSYXN0ZXIoczRfaXBfbGIsICJvdXRwdXQvaGFiaXRhdF9wcmVkL3M0X2lwX2xiLnRpZiIsIG92ZXJ3cml0ZSA9IFRSVUUpCgpzNF9pcF9sYiA8LSByYXN0ZXIoeCA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3M0X2lwX2xiLnRpZiIpCgpwbG90KHM0X2lwX2xiKQpgYGAKCmBgYHtyIHM0X2ZwX2xifQpyZWdpc3RlckRvTUMoY29yZXMgPSAyMCkKCnM0X2ZwX2xiIDwtIGZvcmVhY2goaSA9IHNlcV9sZW4obGVuZ3RoKHM0X2Z2X2xiKSkpICVkb3BhciUgewogIHByZWRpY3QoczRfZnZfbGJbW2ldXSwKICAgICAgICAgIHM0X21vZF9sYiwKICAgICAgICAgIHR5cGUgPSAicmVzcG9uc2UiLAogICAgICAgICAgbi50cmVlcyA9IHM0X21vZF9sYiRnYm0uY2FsbCRiZXN0LnRyZWVzLAogICAgICAgICAgZmlsZW5hbWUgPSBwYXN0ZTAoIm91dHB1dC9oYWJpdGF0X3ByZWQvczRfZnBfbGItIiwgc3ByaW50ZigiJTAzZCIsIGkpLCAiLnRpZiIpLAogICAgICAgICAgb3ZlcndyaXRlID0gVFJVRSkKfQoKczRfZnBfbGIgPC0gc3RhY2soczRfZnBfbGIpCmBgYAoKYGBge3Igc2F2ZSBzNF9mcF9sYn0Kc2F2ZShzNF9mcF9sYiwgZmlsZSA9ICJvdXRwdXQvaGFiaXRhdF9wcmVkL3M0X2ZwX2xiIikKd3JpdGVSYXN0ZXIoczRfZnBfbGIsIGZpbGVuYW1lID0gIm91dHB1dC9oYWJpdGF0X3ByZWQvczRfZnBfbGIudGlmIikKYGBgCgoKCiMgUG9wdWxhdGlvbiB2aWFiaWxpdHkgYW5hbHlzaXMKCiMjIEdyZWF0ZXIgR2xpZGVyCmBgYHtyfQpnZ190cmFuc19tYXQgPC0gbWF0cml4KGMoMC4wMCwwLjAwLDAuMjUsCiAgICAgICAgICAgICAgICAgICAgICAgICAwLjUwLDAuMDAsMC4wMCwKICAgICAgICAgICAgICAgICAgICAgICAgIDAuMDAsMC44NSwwLjg1KSwKICAgICAgICAgICAgICAgICAgICAgICBucm93ID0gMywgbmNvbCA9IDMsIGJ5cm93ID0gVFJVRSkgIyBiYXNlZCBvbiBQb3NzaW5naGFtIGV0IGFsIDE5OTQKY29sbmFtZXMoZ2dfdHJhbnNfbWF0KSA8LSByb3duYW1lcyhnZ190cmFuc19tYXQpIDwtIGMoJ05ld2Jvcm4nLCdKdXZlbmlsZScsJ0FkdWx0JykKCmdnX3N0YWJsZV9zdGF0ZXMgPC0gYWJzKCBlaWdlbihnZ190cmFuc19tYXQpJHZlY3RvcnNbLDFdIC8gYmFzZTo6c3VtKGVpZ2VuKGdnX3RyYW5zX21hdCkkdmVjdG9yc1ssMV0pICkgCmBgYAoKCiMjIyBTY2VuYXJpbyAxCmBgYHtyfQpzMV9oc19nZyA8LSBzdGFjayhzMV9pcF9nZywgczFfZnBfZ2cpCgpmb3IoaSBpbiAxOjUxKXsKICBzMV9oc19nZ1tbaV1dW2lzLm5hKHMxX2hzX2dnW1tpXV1bXSldIDwtIDAKfQoKczFfaHNfZ2cgPC0gbWFzayhzMV9oc19nZywgbWFzayA9IGNoX21hc2spCmBgYAoKYGBge3J9CnMxX2hhYl9rX2dnIDwtIGNhbGMoczFfaHNfZ2dbWzFdXSwgZnVuID0gZnVuY3Rpb24oeCl7aWYoaXMubmEoeCkpIHggZWxzZSByYmlub20ocHJvYiA9IHgsIHNpemUgPSAzLCBuID0gMSl9KQoKbmFtZXMoczFfaGFiX2tfZ2cpIDwtICJjYXJyeWluZ0NhcGFjaXR5IgoKczFfZ2dfcG9wTiA8LSBzdGFjayhyZXBsaWNhdGUobmNvbChnZ190cmFuc19tYXQpLCBzMV9oYWJfa19nZykpCgpzMV9nZ19wb3BOIDwtIHMxX2dnX3BvcE4qZ2dfc3RhYmxlX3N0YXRlcwoKczFfZ2dfaWR4IDwtIHdoaWNoKCFpcy5uYShzMV9oc19nZ1tbMV1dW10pICYgczFfaHNfZ2dbWzFdXVtdIDwgMC45NSkKCnMxX2dnX3BvcCA8LSBzMV9nZ19wb3BOCnMxX2dnX3BvcFshaXMubmEoczFfZ2dfcG9wKV0gPC0gMApzMV9nZ19wb3BbWzFdXVtzYW1wbGUoczFfZ2dfaWR4LCAxMDAwMCldIDwtIDEKczFfZ2dfcG9wW1syXV1bc2FtcGxlKHMxX2dnX2lkeCwgMTAwMDApXSA8LSAxCnMxX2dnX3BvcFtbM11dW3NhbXBsZShzMV9nZ19pZHgsIDEwMDAwKV0gPC0gMQoKczFfZ2dfcG9wIDwtIHMxX2dnX3BvcCpjaF9tYXNrCgpuYW1lcyhzMV9nZ19wb3ApIDwtIGNvbG5hbWVzKGdnX3RyYW5zX21hdCkKCnMxX2dnX1RvdHBvcE4gPC0gc3VtKGNlbGxTdGF0cyhzMV9nZ19wb3AsICdzdW0nLCBuYS5ybSA9IFRSVUUpKSAjIEdldCB0b3RhbCBwb3B1bGF0aW9uIHNpemUgdG8gY2hlY2sgc2Vuc2libGUKczFfZ2dfaW5pdF9wb3Bfc2l6ZSA8LSBzdW0oczFfZ2dfcG9wKQpgYGAKCmBgYHtyfQpzMV9nZ19sYW5kc2NhcGUgPC0gbGFuZHNjYXBlKHBvcHVsYXRpb24gPSBzMV9nZ19wb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3VpdGFiaWxpdHkgPSBzMV9oc19nZywKICAgICAgICAgICAgICAgICAgICAgICAgICBjYXJyeWluZ19jYXBhY2l0eSA9IHMxX2hhYl9rX2dnKQoKczFfZ2dfcG9wX2R5bmFtaWNzIDwtIHBvcHVsYXRpb25fZHluYW1pY3MoY2hhbmdlID0gZ3Jvd3RoKHRyYW5zaXRpb25fbWF0cml4ID0gZ2dfdHJhbnNfbWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xvYmFsX3N0b2NoYXN0aWNpdHkgPSAwLjEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzYWwgPSBmYXN0X2Rpc3BlcnNhbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzYWxfa2VybmVsID0gZXhwb25lbnRpYWxfZGlzcGVyc2FsX2tlcm5lbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlX2RlY2F5ID0gODAwMCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmljYXRpb24gPSBOVUxMKQpgYGAKCmBgYHtyfQpwbGFuKHNlcXVlbnRpYWwsIHdvcmtlcnMgPSAxKQpzMV9nZ19yZXN1bHRzXzFfNTAgPC0gc2ltdWxhdGlvbihsYW5kc2NhcGUgPSBzMV9nZ19sYW5kc2NhcGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uX2R5bmFtaWNzID0gczFfZ2dfcG9wX2R5bmFtaWNzLAogICAgICAgICAgICAgICAgICAgICAgICAgaGFiaXRhdF9keW5hbWljcyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RlcHMgPSA1MCwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxpY2F0ZXMgPSAxKQoKCnNhdmVSRFMob2JqZWN0ID0gczFfZ2dfcmVzdWx0c18xXzUwLCBmaWxlID0gIm91dHB1dC9wdmFfcmVzdWx0cy9zMV9nZ19yZXN1bHRzXzFfNTAuUmRzIikKYGBgCgoKYGBge3J9CnBsb3QoczFfZ2dfcmVzdWx0c18xXzUwKQpgYGAKCmBgYHtyfQpwbG90KHMxX2dnX3Jlc3VsdHNfMV81MFsxXSwgdHlwZSA9ICJyYXN0ZXIiLCBzdGFnZXMgPSAwLCB0aW1lc3RlcHMgPSBjKDE6NSkpCmBgYAoKIyMjIFNjZW5hcmlvIDMKYGBge3J9CnMzX2hzX2dnIDwtIHN0YWNrKHMzX2lwX2dnLCBzM19mcF9nZykKCmZvcihpIGluIDE6NTEpewogIHMzX2hzX2dnW1tpXV1baXMubmEoczNfaHNfZ2dbW2ldXVtdKV0gPC0gMAp9CgpzM19oc19nZyA8LSBtYXNrKHMzX2hzX2dnLCBtYXNrID0gY2hfbWFzaykKYGBgCgpgYGB7cn0KczNfaGFiX2tfZ2cgPC0gY2FsYyhzM19oc19nZ1tbMV1dLCBmdW4gPSBmdW5jdGlvbih4KXtpZihpcy5uYSh4KSkgeCBlbHNlIHJiaW5vbShwcm9iID0geCwgc2l6ZSA9IDMsIG4gPSAxKX0pCgpuYW1lcyhzM19oYWJfa19nZykgPC0gImNhcnJ5aW5nQ2FwYWNpdHkiCgpzM19nZ19wb3BOIDwtIHN0YWNrKHJlcGxpY2F0ZShuY29sKGdnX3RyYW5zX21hdCksIHMzX2hhYl9rX2dnKSkKCnMzX2dnX3BvcE4gPC0gczNfZ2dfcG9wTipnZ19zdGFibGVfc3RhdGVzCgpzM19nZ19pZHggPC0gd2hpY2goIWlzLm5hKHMzX2hzX2dnW1sxXV1bXSkgJiBzM19oc19nZ1tbMV1dW10gPCAwLjk1KQoKczNfZ2dfcG9wIDwtIHMzX2dnX3BvcE4KczNfZ2dfcG9wWyFpcy5uYShzM19nZ19wb3ApXSA8LSAwCnMzX2dnX3BvcFtbMV1dW3NhbXBsZShzM19nZ19pZHgsIDEwMDAwKV0gPC0gMQpzM19nZ19wb3BbWzJdXVtzYW1wbGUoczNfZ2dfaWR4LCAxMDAwMCldIDwtIDEKczNfZ2dfcG9wW1szXV1bc2FtcGxlKHMzX2dnX2lkeCwgMTAwMDApXSA8LSAxCgpzM19nZ19wb3AgPC0gczNfZ2dfcG9wKmNoX21hc2sKCm5hbWVzKHMzX2dnX3BvcCkgPC0gY29sbmFtZXMoZ2dfdHJhbnNfbWF0KQoKczNfZ2dfVG90cG9wTiA8LSBzdW0oY2VsbFN0YXRzKHMzX2dnX3BvcCwgJ3N1bScsIG5hLnJtID0gVFJVRSkpICMgR2V0IHRvdGFsIHBvcHVsYXRpb24gc2l6ZSB0byBjaGVjayBzZW5zaWJsZQpzM19nZ19pbml0X3BvcF9zaXplIDwtIHN1bShzM19nZ19wb3ApCmBgYAoKYGBge3J9CnMzX2dnX2xhbmRzY2FwZSA8LSBsYW5kc2NhcGUocG9wdWxhdGlvbiA9IHMzX2dnX3BvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdWl0YWJpbGl0eSA9IHMzX2hzX2dnLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNhcnJ5aW5nX2NhcGFjaXR5ID0gczNfaGFiX2tfZ2cpCgpzM19nZ19wb3BfZHluYW1pY3MgPC0gcG9wdWxhdGlvbl9keW5hbWljcyhjaGFuZ2UgPSBncm93dGgodHJhbnNpdGlvbl9tYXRyaXggPSBnZ190cmFuc19tYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbG9iYWxfc3RvY2hhc3RpY2l0eSA9IDAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BlcnNhbCA9IGZhc3RfZGlzcGVyc2FsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BlcnNhbF9rZXJuZWwgPSBleHBvbmVudGlhbF9kaXNwZXJzYWxfa2VybmVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2VfZGVjYXkgPSA4MDAwKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWNhdGlvbiA9IE5VTEwpCmBgYAoKYGBge3J9CnBsYW4oc2VxdWVudGlhbCwgd29ya2VycyA9IDEpCnMzX2dnX3Jlc3VsdHNfMV81MCA8LSBzaW11bGF0aW9uKGxhbmRzY2FwZSA9IHMzX2dnX2xhbmRzY2FwZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBvcHVsYXRpb25fZHluYW1pY3MgPSBzM19nZ19wb3BfZHluYW1pY3MsCiAgICAgICAgICAgICAgICAgICAgICAgICBoYWJpdGF0X2R5bmFtaWNzID0gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzdGVwcyA9IDUwLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGljYXRlcyA9IDEpCgoKc2F2ZVJEUyhvYmplY3QgPSBzM19nZ19yZXN1bHRzXzFfNTAsIGZpbGUgPSAib3V0cHV0L3B2YV9yZXN1bHRzL3MzX2dnX3Jlc3VsdHNfMV81MC5SZHMiKQpgYGAKCgpgYGB7cn0KcGxvdChzM19nZ19yZXN1bHRzXzFfNTApCmBgYAoKYGBge3J9CnBsb3QoczNfZ2dfcmVzdWx0c18xXzUwWzFdLCB0eXBlID0gInJhc3RlciIsIHN0YWdlcyA9IDAsIHRpbWVzdGVwcyA9IGMoMTo1KSkKYGBgCgojIyMgU2NlbmFyaW8gNApgYGB7cn0KczRfaHNfZ2cgPC0gc3RhY2soczRfaXBfZ2csIHM0X2ZwX2dnKQoKZm9yKGkgaW4gMTo1MSl7CiAgczRfaHNfZ2dbW2ldXVtpcy5uYShzNF9oc19nZ1tbaV1dW10pXSA8LSAwCn0KCnM0X2hzX2dnIDwtIG1hc2soczRfaHNfZ2csIG1hc2sgPSBjaF9tYXNrKQpgYGAKCmBgYHtyfQpzNF9oYWJfa19nZyA8LSBjYWxjKHM0X2hzX2dnW1sxXV0sIGZ1biA9IGZ1bmN0aW9uKHgpe2lmKGlzLm5hKHgpKSB4IGVsc2UgcmJpbm9tKHByb2IgPSB4LCBzaXplID0gMywgbiA9IDEpfSkKCm5hbWVzKHM0X2hhYl9rX2dnKSA8LSAiY2FycnlpbmdDYXBhY2l0eSIKCnM0X2dnX3BvcE4gPC0gc3RhY2socmVwbGljYXRlKG5jb2woZ2dfdHJhbnNfbWF0KSwgczRfaGFiX2tfZ2cpKQoKczRfZ2dfcG9wTiA8LSBzNF9nZ19wb3BOKmdnX3N0YWJsZV9zdGF0ZXMKCnM0X2dnX2lkeCA8LSB3aGljaCghaXMubmEoczRfaHNfZ2dbWzFdXVtdKSAmIHM0X2hzX2dnW1sxXV1bXSA8IDAuOTUpCgpzNF9nZ19wb3AgPC0gczRfZ2dfcG9wTgpzNF9nZ19wb3BbIWlzLm5hKHM0X2dnX3BvcCldIDwtIDAKczRfZ2dfcG9wW1sxXV1bc2FtcGxlKHM0X2dnX2lkeCwgMTAwMDApXSA8LSAxCnM0X2dnX3BvcFtbMl1dW3NhbXBsZShzNF9nZ19pZHgsIDEwMDAwKV0gPC0gMQpzNF9nZ19wb3BbWzNdXVtzYW1wbGUoczRfZ2dfaWR4LCAxMDAwMCldIDwtIDEKCnM0X2dnX3BvcCA8LSBzNF9nZ19wb3AqY2hfbWFzawoKbmFtZXMoczRfZ2dfcG9wKSA8LSBjb2xuYW1lcyhnZ190cmFuc19tYXQpCgpzNF9nZ19Ub3Rwb3BOIDwtIHN1bShjZWxsU3RhdHMoczRfZ2dfcG9wLCAnc3VtJywgbmEucm0gPSBUUlVFKSkgIyBHZXQgdG90YWwgcG9wdWxhdGlvbiBzaXplIHRvIGNoZWNrIHNlbnNpYmxlCnM0X2dnX2luaXRfcG9wX3NpemUgPC0gc3VtKHM0X2dnX3BvcCkKYGBgCgpgYGB7cn0KczRfZ2dfbGFuZHNjYXBlIDwtIGxhbmRzY2FwZShwb3B1bGF0aW9uID0gczRfZ2dfcG9wLAogICAgICAgICAgICAgICAgICAgICAgICAgIHN1aXRhYmlsaXR5ID0gczRfaHNfZ2csCiAgICAgICAgICAgICAgICAgICAgICAgICAgY2FycnlpbmdfY2FwYWNpdHkgPSBzNF9oYWJfa19nZykKCnM0X2dnX3BvcF9keW5hbWljcyA8LSBwb3B1bGF0aW9uX2R5bmFtaWNzKGNoYW5nZSA9IGdyb3d0aCh0cmFuc2l0aW9uX21hdHJpeCA9IGdnX3RyYW5zX21hdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdsb2JhbF9zdG9jaGFzdGljaXR5ID0gMC4xKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGVyc2FsID0gZmFzdF9kaXNwZXJzYWwoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzcGVyc2FsX2tlcm5lbCA9IGV4cG9uZW50aWFsX2Rpc3BlcnNhbF9rZXJuZWwoCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXN0YW5jZV9kZWNheSA9IDgwMDApKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kaWZpY2F0aW9uID0gTlVMTCkKYGBgCgpgYGB7cn0KcGxhbihzZXF1ZW50aWFsLCB3b3JrZXJzID0gMSkKczRfZ2dfcmVzdWx0c18xXzUwIDwtIHNpbXVsYXRpb24obGFuZHNjYXBlID0gczRfZ2dfbGFuZHNjYXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgcG9wdWxhdGlvbl9keW5hbWljcyA9IHM0X2dnX3BvcF9keW5hbWljcywKICAgICAgICAgICAgICAgICAgICAgICAgIGhhYml0YXRfZHluYW1pY3MgPSBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgdGltZXN0ZXBzID0gNTAsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXBsaWNhdGVzID0gMSkKCgpzYXZlUkRTKG9iamVjdCA9IHM0X2dnX3Jlc3VsdHNfMV81MCwgZmlsZSA9ICJvdXRwdXQvcHZhX3Jlc3VsdHMvczRfZ2dfcmVzdWx0c18xXzUwLlJkcyIpCmBgYAoKCmBgYHtyfQpwbG90KHM0X2dnX3Jlc3VsdHNfMV81MCkKYGBgCgpgYGB7cn0KcGxvdChzNF9nZ19yZXN1bHRzXzFfNTBbMV0sIHR5cGUgPSAicmFzdGVyIiwgc3RhZ2VzID0gMCwgdGltZXN0ZXBzID0gYygxOjUpKQpgYGAKCgojIyBMZWFkYmVhdGVyJ3MgUG9zc3VtCmBgYHtyfQpsYl90cmFuc19tYXQgPC0gbWF0cml4KGMoMC4wMCwgMC4wMCwgMS4xMCwKICAgICAgICAgICAgICAgICAgICAgICAgIDAuNTksIDAuMDAsIDAuMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAwLjAwLCAwLjU5LCAwLjc5KSwKICAgICAgICAgICAgICAgICAgICAgICBucm93ID0gMywgbmNvbCA9IDMsIGJ5cm93ID0gVFJVRSkgCmNvbG5hbWVzKGxiX3RyYW5zX21hdCkgPC0gcm93bmFtZXMobGJfdHJhbnNfbWF0KSA8LSBjKCdOZXdib3JuJywnSnV2ZW5pbGUnLCdBZHVsdCcpCgpsYl9zdGFibGVfc3RhdGVzIDwtIGFicyggZWlnZW4obGJfdHJhbnNfbWF0KSR2ZWN0b3JzWywxXSAvIGJhc2U6OnN1bShlaWdlbihsYl90cmFuc19tYXQpJHZlY3RvcnNbLDFdKSApIApgYGAKCiMjIyBTY2VuYXJpbyAxCmBgYHtyfQpzMV9oc19sYiA8LSBzdGFjayhzMV9pcF9sYiwgczFfZnBfbGIpCgpmb3IoaSBpbiAxOjUxKXsKICBzMV9oc19sYltbaV1dW2lzLm5hKHMxX2hzX2xiW1tpXV1bXSldIDwtIDAKfQoKczFfaHNfbGIgPC0gbWFzayhzMV9oc19sYiwgbWFzayA9IGNoX21hc2spCmBgYAoKYGBge3J9CnMxX2hhYl9rX2xiIDwtIGNhbGMoczFfaHNfbGJbWzFdXSwgZnVuID0gZnVuY3Rpb24oeCl7aWYoaXMubmEoeCkpIHggZWxzZSByYmlub20ocHJvYiA9IHgsIHNpemUgPSAzLCBuID0gMSl9KQoKbmFtZXMoczFfaGFiX2tfbGIpIDwtICJjYXJyeWluZ0NhcGFjaXR5IgoKczFfbGJfcG9wTiA8LSBzdGFjayhyZXBsaWNhdGUobmNvbChsYl90cmFuc19tYXQpLCBzMV9oYWJfa19sYikpCgpzMV9sYl9wb3BOIDwtIHMxX2xiX3BvcE4qbGJfc3RhYmxlX3N0YXRlcwoKczFfbGJfaWR4IDwtIHdoaWNoKCFpcy5uYShzMV9oc19sYltbMV1dW10pICYgczFfaHNfbGJbWzFdXVtdIDwgMC45NSkKCnMxX2xiX3BvcCA8LSBzMV9sYl9wb3BOCnMxX2xiX3BvcFshaXMubmEoczFfbGJfcG9wKV0gPC0gMApzMV9sYl9wb3BbWzFdXVtzYW1wbGUoczFfbGJfaWR4LCAzMDAwKV0gPC0gMQpzMV9sYl9wb3BbWzJdXVtzYW1wbGUoczFfbGJfaWR4LCAzMDAwKV0gPC0gMQpzMV9sYl9wb3BbWzNdXVtzYW1wbGUoczFfbGJfaWR4LCAzMDAwKV0gPC0gMQoKczFfbGJfcG9wIDwtIHMxX2xiX3BvcCpjaF9tYXNrCgpuYW1lcyhzMV9sYl9wb3ApIDwtIGNvbG5hbWVzKGxiX3RyYW5zX21hdCkKCnMxX2xiX1RvdHBvcE4gPC0gc3VtKGNlbGxTdGF0cyhzMV9sYl9wb3AsICdzdW0nLCBuYS5ybSA9IFRSVUUpKSAjIEdldCB0b3RhbCBwb3B1bGF0aW9uIHNpemUgdG8gY2hlY2sgc2Vuc2libGUKczFfbGJfaW5pdF9wb3Bfc2l6ZSA8LSBzdW0oczFfbGJfcG9wKQpgYGAKCmBgYHtyfQpzMV9sYl9sYW5kc2NhcGUgPC0gbGFuZHNjYXBlKHBvcHVsYXRpb24gPSBzMV9sYl9wb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3VpdGFiaWxpdHkgPSBzMV9oc19sYiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjYXJyeWluZ19jYXBhY2l0eSA9IHMxX2hhYl9rX2xiKQoKczFfbGJfcG9wX2R5bmFtaWNzIDwtIHBvcHVsYXRpb25fZHluYW1pY3MoY2hhbmdlID0gZ3Jvd3RoKHRyYW5zaXRpb25fbWF0cml4ID0gbGJfdHJhbnNfbWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xvYmFsX3N0b2NoYXN0aWNpdHkgPSAwLjMpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzYWwgPSBmYXN0X2Rpc3BlcnNhbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzYWxfa2VybmVsID0gZXhwb25lbnRpYWxfZGlzcGVyc2FsX2tlcm5lbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlX2RlY2F5ID0gMjAwMCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmljYXRpb24gPSBOVUxMKQpgYGAKCmBgYHtyfQpwbGFuKHNlcXVlbnRpYWwsIHdvcmtlcnMgPSAxKQpzMV9sYl9yZXN1bHRzXzFfNTAgPC0gc2ltdWxhdGlvbihsYW5kc2NhcGUgPSBzMV9sYl9sYW5kc2NhcGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uX2R5bmFtaWNzID0gczFfbGJfcG9wX2R5bmFtaWNzLAogICAgICAgICAgICAgICAgICAgICAgICAgaGFiaXRhdF9keW5hbWljcyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RlcHMgPSA1MCwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxpY2F0ZXMgPSAxKQoKCnNhdmVSRFMob2JqZWN0ID0gczFfbGJfcmVzdWx0c18xXzUwLCBmaWxlID0gIm91dHB1dC9wdmFfcmVzdWx0cy9zMV9sYl9yZXN1bHRzXzFfNTAuUmRzIikKYGBgCgoKYGBge3J9CnBsb3QoczFfbGJfcmVzdWx0c18xXzUwKQpgYGAKCmBgYHtyfQpwbG90KHMxX2xiX3Jlc3VsdHNfMV81MFsxXSwgdHlwZSA9ICJyYXN0ZXIiLCBzdGFnZXMgPSAwLCB0aW1lc3RlcHMgPSBjKDE6NSkpCmBgYAoKIyMjIFNjZW5hcmlvIDMKYGBge3J9CnMzX2hzX2xiIDwtIHN0YWNrKHMzX2lwX2xiLCBzM19mcF9sYikKCmZvcihpIGluIDE6NTEpewogIHMzX2hzX2xiW1tpXV1baXMubmEoczNfaHNfbGJbW2ldXVtdKV0gPC0gMAp9CgpzM19oc19sYiA8LSBtYXNrKHMzX2hzX2xiLCBtYXNrID0gY2hfbWFzaykKYGBgCgpgYGB7cn0KczNfaGFiX2tfbGIgPC0gY2FsYyhzM19oc19sYltbMV1dLCBmdW4gPSBmdW5jdGlvbih4KXtpZihpcy5uYSh4KSkgeCBlbHNlIHJiaW5vbShwcm9iID0geCwgc2l6ZSA9IDMsIG4gPSAxKX0pCgpuYW1lcyhzM19oYWJfa19sYikgPC0gImNhcnJ5aW5nQ2FwYWNpdHkiCgpzM19sYl9wb3BOIDwtIHN0YWNrKHJlcGxpY2F0ZShuY29sKGxiX3RyYW5zX21hdCksIHMzX2hhYl9rX2xiKSkKCnMzX2xiX3BvcE4gPC0gczNfbGJfcG9wTipsYl9zdGFibGVfc3RhdGVzCgpzM19sYl9pZHggPC0gd2hpY2goIWlzLm5hKHMzX2hzX2xiW1sxXV1bXSkgJiBzM19oc19sYltbMV1dW10gPCAwLjk1KQoKczNfbGJfcG9wIDwtIHMzX2xiX3BvcE4KczNfbGJfcG9wWyFpcy5uYShzM19sYl9wb3ApXSA8LSAwCnMzX2xiX3BvcFtbMV1dW3NhbXBsZShzM19sYl9pZHgsIDMwMDApXSA8LSAxCnMzX2xiX3BvcFtbMl1dW3NhbXBsZShzM19sYl9pZHgsIDMwMDApXSA8LSAxCnMzX2xiX3BvcFtbM11dW3NhbXBsZShzM19sYl9pZHgsIDMwMDApXSA8LSAxCgpzM19sYl9wb3AgPC0gczNfbGJfcG9wKmNoX21hc2sKCm5hbWVzKHMzX2xiX3BvcCkgPC0gY29sbmFtZXMobGJfdHJhbnNfbWF0KQoKczNfbGJfVG90cG9wTiA8LSBzdW0oY2VsbFN0YXRzKHMzX2xiX3BvcCwgJ3N1bScsIG5hLnJtID0gVFJVRSkpICMgR2V0IHRvdGFsIHBvcHVsYXRpb24gc2l6ZSB0byBjaGVjayBzZW5zaWJsZQpzM19sYl9pbml0X3BvcF9zaXplIDwtIHN1bShzM19sYl9wb3ApCmBgYAoKYGBge3J9CnMzX2xiX2xhbmRzY2FwZSA8LSBsYW5kc2NhcGUocG9wdWxhdGlvbiA9IHMzX2xiX3BvcCwKICAgICAgICAgICAgICAgICAgICAgICAgICBzdWl0YWJpbGl0eSA9IHMzX2hzX2xiLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNhcnJ5aW5nX2NhcGFjaXR5ID0gczNfaGFiX2tfbGIpCgpzM19sYl9wb3BfZHluYW1pY3MgPC0gcG9wdWxhdGlvbl9keW5hbWljcyhjaGFuZ2UgPSBncm93dGgodHJhbnNpdGlvbl9tYXRyaXggPSBsYl90cmFuc19tYXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnbG9iYWxfc3RvY2hhc3RpY2l0eSA9IDAuMSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BlcnNhbCA9IGZhc3RfZGlzcGVyc2FsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3BlcnNhbF9rZXJuZWwgPSBleHBvbmVudGlhbF9kaXNwZXJzYWxfa2VybmVsKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdGFuY2VfZGVjYXkgPSA4MDAwKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vZGlmaWNhdGlvbiA9IE5VTEwpCmBgYAoKYGBge3J9CnBsYW4oc2VxdWVudGlhbCwgd29ya2VycyA9IDEpCnMzX2xiX3Jlc3VsdHNfMV81MCA8LSBzaW11bGF0aW9uKGxhbmRzY2FwZSA9IHMzX2xiX2xhbmRzY2FwZSwKICAgICAgICAgICAgICAgICAgICAgICAgIHBvcHVsYXRpb25fZHluYW1pY3MgPSBzM19sYl9wb3BfZHluYW1pY3MsCiAgICAgICAgICAgICAgICAgICAgICAgICBoYWJpdGF0X2R5bmFtaWNzID0gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVzdGVwcyA9IDUwLAogICAgICAgICAgICAgICAgICAgICAgICAgcmVwbGljYXRlcyA9IDEpCgoKc2F2ZVJEUyhvYmplY3QgPSBzM19sYl9yZXN1bHRzXzFfNTAsIGZpbGUgPSAib3V0cHV0L3B2YV9yZXN1bHRzL3MzX2xiX3Jlc3VsdHNfMV81MC5SZHMiKQpgYGAKCmBgYHtyfQpwbG90KHMzX2xiX3Jlc3VsdHNfMV81MCkKYGBgCgpgYGB7cn0KcGxvdChzM19sYl9yZXN1bHRzXzFfNTBbMV0sIHR5cGUgPSAicmFzdGVyIiwgc3RhZ2VzID0gMCwgdGltZXN0ZXBzID0gYygxOjUpKQpgYGAKCiMjIyBTY2VuYXJpbyA0CmBgYHtyfQpzNF9oc19sYiA8LSBzdGFjayhzNF9pcF9sYiwgczRfZnBfbGIpCgpmb3IoaSBpbiAxOjUxKXsKICBzNF9oc19sYltbaV1dW2lzLm5hKHM0X2hzX2xiW1tpXV1bXSldIDwtIDAKfQoKczRfaHNfbGIgPC0gbWFzayhzNF9oc19sYiwgbWFzayA9IGNoX21hc2spCmBgYAoKYGBge3J9CnM0X2hhYl9rX2xiIDwtIGNhbGMoczRfaHNfbGJbWzFdXSwgZnVuID0gZnVuY3Rpb24oeCl7aWYoaXMubmEoeCkpIHggZWxzZSByYmlub20ocHJvYiA9IHgsIHNpemUgPSAzLCBuID0gMSl9KQoKbmFtZXMoczRfaGFiX2tfbGIpIDwtICJjYXJyeWluZ0NhcGFjaXR5IgoKczRfbGJfcG9wTiA8LSBzdGFjayhyZXBsaWNhdGUobmNvbChsYl90cmFuc19tYXQpLCBzNF9oYWJfa19sYikpCgpzNF9sYl9wb3BOIDwtIHM0X2xiX3BvcE4qbGJfc3RhYmxlX3N0YXRlcwoKczRfbGJfaWR4IDwtIHdoaWNoKCFpcy5uYShzNF9oc19sYltbMV1dW10pICYgczRfaHNfbGJbWzFdXVtdIDwgMC45NSkKCnM0X2xiX3BvcCA8LSBzNF9sYl9wb3BOCnM0X2xiX3BvcFshaXMubmEoczRfbGJfcG9wKV0gPC0gMApzNF9sYl9wb3BbWzFdXVtzYW1wbGUoczRfbGJfaWR4LCAzMDAwKV0gPC0gMQpzNF9sYl9wb3BbWzJdXVtzYW1wbGUoczRfbGJfaWR4LCAzMDAwKV0gPC0gMQpzNF9sYl9wb3BbWzNdXVtzYW1wbGUoczRfbGJfaWR4LCAzMDAwKV0gPC0gMQoKczRfbGJfcG9wIDwtIHM0X2xiX3BvcCpjaF9tYXNrCgpuYW1lcyhzNF9sYl9wb3ApIDwtIGNvbG5hbWVzKGxiX3RyYW5zX21hdCkKCnM0X2xiX1RvdHBvcE4gPC0gc3VtKGNlbGxTdGF0cyhzNF9sYl9wb3AsICdzdW0nLCBuYS5ybSA9IFRSVUUpKSAjIEdldCB0b3RhbCBwb3B1bGF0aW9uIHNpemUgdG8gY2hlY2sgc2Vuc2libGUKczRfbGJfaW5pdF9wb3Bfc2l6ZSA8LSBzdW0oczRfbGJfcG9wKQpgYGAKCmBgYHtyfQpzNF9sYl9sYW5kc2NhcGUgPC0gbGFuZHNjYXBlKHBvcHVsYXRpb24gPSBzNF9sYl9wb3AsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc3VpdGFiaWxpdHkgPSBzNF9oc19sYiwKICAgICAgICAgICAgICAgICAgICAgICAgICBjYXJyeWluZ19jYXBhY2l0eSA9IHM0X2hhYl9rX2xiKQoKczRfbGJfcG9wX2R5bmFtaWNzIDwtIHBvcHVsYXRpb25fZHluYW1pY3MoY2hhbmdlID0gZ3Jvd3RoKHRyYW5zaXRpb25fbWF0cml4ID0gbGJfdHJhbnNfbWF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xvYmFsX3N0b2NoYXN0aWNpdHkgPSAwLjEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzYWwgPSBmYXN0X2Rpc3BlcnNhbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNwZXJzYWxfa2VybmVsID0gZXhwb25lbnRpYWxfZGlzcGVyc2FsX2tlcm5lbCgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3RhbmNlX2RlY2F5ID0gODAwMCkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RpZmljYXRpb24gPSBOVUxMKQpgYGAKCmBgYHtyfQpwbGFuKHNlcXVlbnRpYWwsIHdvcmtlcnMgPSAxKQpzNF9sYl9yZXN1bHRzXzFfNTAgPC0gc2ltdWxhdGlvbihsYW5kc2NhcGUgPSBzNF9sYl9sYW5kc2NhcGUsCiAgICAgICAgICAgICAgICAgICAgICAgICBwb3B1bGF0aW9uX2R5bmFtaWNzID0gczRfbGJfcG9wX2R5bmFtaWNzLAogICAgICAgICAgICAgICAgICAgICAgICAgaGFiaXRhdF9keW5hbWljcyA9IE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lc3RlcHMgPSA1MCwKICAgICAgICAgICAgICAgICAgICAgICAgIHJlcGxpY2F0ZXMgPSAxKQoKCnNhdmVSRFMob2JqZWN0ID0gczRfbGJfcmVzdWx0c18xXzUwLCBmaWxlID0gIm91dHB1dC9wdmFfcmVzdWx0cy9zNF9sYl9yZXN1bHRzXzFfNTAuUmRzIikKYGBgCgoKYGBge3J9CnBsb3QoczRfbGJfcmVzdWx0c18xXzUwKQpgYGAKCmBgYHtyfQpwbG90KHM0X2xiX3Jlc3VsdHNfMV81MFsxXSwgdHlwZSA9ICJyYXN0ZXIiLCBzdGFnZXMgPSAwLCB0aW1lc3RlcHMgPSBjKDE6NSkpCmBgYAoKCg==